aboutsummaryrefslogblamecommitdiffstats
path: root/core/vm/opcodes.go
blob: 8762d4b438708f2e46f8d28892f2f3e6b44dcd7b (plain) (tree)
1
2
3
4
5
6
7
8
9
                                         
                                                
  
                                                                                  



                                                                              
                                                                             
                                                                 
                                                               


                                                                           
                                                                                  
 
          




             
                          
                
 
                                                  







                                                                                                                                                                                                                                                                   
                                               



                                      
                              
       












                          
 
                               











                               


           
 
                   
                   
 
 
                              
       












                                    

                      
                   

 
                                 
       
                                      





                  
 
                                        
       












                                
 
              
       
































































                                  
 
                            







                                 
                                       





                                 
                         
       

                                   
                
              
                    
               
                         
 
                           
                           

 
                                                                      
                                       
                                      
















                                 
 
                                



                       


                      

                         
 
                               
                     
                     
 
                                      














                                         
                                      
 
                                         





                                 
 
                                                


                          










                             
 
                             
































                         
































                         




                       
 
                      




                                     
                                
                                   
                               
                                     
 


                     

 

                                  
                          
                                                                  



                  

                                   




















                                     


                              


                                 
                               
















                                         
                                      























































































                                     
                                  


                                   
                                 
                                       

 
                                                             


                                    
// Copyright 2014 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package vm

import (
    "fmt"
)

// OpCode is an EVM opcode
type OpCode byte

// IsPush specifies if an opcode is a PUSH opcode.
func (op OpCode) IsPush() bool {
    switch op {
    case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
        return true
    }
    return false
}

// IsStaticJump specifies if an opcode is JUMP.
func (op OpCode) IsStaticJump() bool {
    return op == JUMP
}

// 0x0 range - arithmetic ops.
const (
    STOP OpCode = iota
    ADD
    MUL
    SUB
    DIV
    SDIV
    MOD
    SMOD
    ADDMOD
    MULMOD
    EXP
    SIGNEXTEND
)

// 0x10 range - comparison ops.
const (
    LT OpCode = iota + 0x10
    GT
    SLT
    SGT
    EQ
    ISZERO
    AND
    OR
    XOR
    NOT
    BYTE
    SHL
    SHR
    SAR

    SHA3 = 0x20
    RAND = 0x2f
)

// 0x30 range - closure state.
const (
    ADDRESS OpCode = 0x30 + iota
    BALANCE
    ORIGIN
    CALLER
    CALLVALUE
    CALLDATALOAD
    CALLDATASIZE
    CALLDATACOPY
    CODESIZE
    CODECOPY
    GASPRICE
    EXTCODESIZE
    EXTCODECOPY
    RETURNDATASIZE
    RETURNDATACOPY
    EXTCODEHASH
)

// 0x40 range - block operations.
const (
    BLOCKHASH OpCode = 0x40 + iota
    COINBASE
    TIMESTAMP
    NUMBER
    DIFFICULTY
    GASLIMIT
)

// 0x50 range - 'storage' and execution.
const (
    POP OpCode = 0x50 + iota
    MLOAD
    MSTORE
    MSTORE8
    SLOAD
    SSTORE
    JUMP
    JUMPI
    PC
    MSIZE
    GAS
    JUMPDEST
)

// 0x60 range.
const (
    PUSH1 OpCode = 0x60 + iota
    PUSH2
    PUSH3
    PUSH4
    PUSH5
    PUSH6
    PUSH7
    PUSH8
    PUSH9
    PUSH10
    PUSH11
    PUSH12
    PUSH13
    PUSH14
    PUSH15
    PUSH16
    PUSH17
    PUSH18
    PUSH19
    PUSH20
    PUSH21
    PUSH22
    PUSH23
    PUSH24
    PUSH25
    PUSH26
    PUSH27
    PUSH28
    PUSH29
    PUSH30
    PUSH31
    PUSH32
    DUP1
    DUP2
    DUP3
    DUP4
    DUP5
    DUP6
    DUP7
    DUP8
    DUP9
    DUP10
    DUP11
    DUP12
    DUP13
    DUP14
    DUP15
    DUP16
    SWAP1
    SWAP2
    SWAP3
    SWAP4
    SWAP5
    SWAP6
    SWAP7
    SWAP8
    SWAP9
    SWAP10
    SWAP11
    SWAP12
    SWAP13
    SWAP14
    SWAP15
    SWAP16
)

// 0xa0 range - logging ops.
const (
    LOG0 OpCode = 0xa0 + iota
    LOG1
    LOG2
    LOG3
    LOG4
)

// unofficial opcodes used for parsing.
const (
    PUSH OpCode = 0xb0 + iota
    DUP
    SWAP
)

// 0xf0 range - closures.
const (
    CREATE OpCode = 0xf0 + iota
    CALL
    CALLCODE
    RETURN
    DELEGATECALL
    CREATE2
    STATICCALL = 0xfa

    REVERT       = 0xfd
    SELFDESTRUCT = 0xff
)

// Since the opcodes aren't all in order we can't use a regular slice.
var opCodeToString = map[OpCode]string{
    // 0x0 range - arithmetic ops.
    STOP:       "STOP",
    ADD:        "ADD",
    MUL:        "MUL",
    SUB:        "SUB",
    DIV:        "DIV",
    SDIV:       "SDIV",
    MOD:        "MOD",
    SMOD:       "SMOD",
    EXP:        "EXP",
    NOT:        "NOT",
    LT:         "LT",
    GT:         "GT",
    SLT:        "SLT",
    SGT:        "SGT",
    EQ:         "EQ",
    ISZERO:     "ISZERO",
    SIGNEXTEND: "SIGNEXTEND",

    // 0x10 range - bit ops.
    AND:    "AND",
    OR:     "OR",
    XOR:    "XOR",
    BYTE:   "BYTE",
    SHL:    "SHL",
    SHR:    "SHR",
    SAR:    "SAR",
    ADDMOD: "ADDMOD",
    MULMOD: "MULMOD",

    // 0x20 range - crypto.
    SHA3: "SHA3",
    RAND: "RAND",

    // 0x30 range - closure state.
    ADDRESS:        "ADDRESS",
    BALANCE:        "BALANCE",
    ORIGIN:         "ORIGIN",
    CALLER:         "CALLER",
    CALLVALUE:      "CALLVALUE",
    CALLDATALOAD:   "CALLDATALOAD",
    CALLDATASIZE:   "CALLDATASIZE",
    CALLDATACOPY:   "CALLDATACOPY",
    CODESIZE:       "CODESIZE",
    CODECOPY:       "CODECOPY",
    GASPRICE:       "GASPRICE",
    EXTCODESIZE:    "EXTCODESIZE",
    EXTCODECOPY:    "EXTCODECOPY",
    RETURNDATASIZE: "RETURNDATASIZE",
    RETURNDATACOPY: "RETURNDATACOPY",
    EXTCODEHASH:    "EXTCODEHASH",

    // 0x40 range - block operations.
    BLOCKHASH:  "BLOCKHASH",
    COINBASE:   "COINBASE",
    TIMESTAMP:  "TIMESTAMP",
    NUMBER:     "NUMBER",
    DIFFICULTY: "DIFFICULTY",
    GASLIMIT:   "GASLIMIT",

    // 0x50 range - 'storage' and execution.
    POP: "POP",
    //DUP:     "DUP",
    //SWAP:    "SWAP",
    MLOAD:    "MLOAD",
    MSTORE:   "MSTORE",
    MSTORE8:  "MSTORE8",
    SLOAD:    "SLOAD",
    SSTORE:   "SSTORE",
    JUMP:     "JUMP",
    JUMPI:    "JUMPI",
    PC:       "PC",
    MSIZE:    "MSIZE",
    GAS:      "GAS",
    JUMPDEST: "JUMPDEST",

    // 0x60 range - push.
    PUSH1:  "PUSH1",
    PUSH2:  "PUSH2",
    PUSH3:  "PUSH3",
    PUSH4:  "PUSH4",
    PUSH5:  "PUSH5",
    PUSH6:  "PUSH6",
    PUSH7:  "PUSH7",
    PUSH8:  "PUSH8",
    PUSH9:  "PUSH9",
    PUSH10: "PUSH10",
    PUSH11: "PUSH11",
    PUSH12: "PUSH12",
    PUSH13: "PUSH13",
    PUSH14: "PUSH14",
    PUSH15: "PUSH15",
    PUSH16: "PUSH16",
    PUSH17: "PUSH17",
    PUSH18: "PUSH18",
    PUSH19: "PUSH19",
    PUSH20: "PUSH20",
    PUSH21: "PUSH21",
    PUSH22: "PUSH22",
    PUSH23: "PUSH23",
    PUSH24: "PUSH24",
    PUSH25: "PUSH25",
    PUSH26: "PUSH26",
    PUSH27: "PUSH27",
    PUSH28: "PUSH28",
    PUSH29: "PUSH29",
    PUSH30: "PUSH30",
    PUSH31: "PUSH31",
    PUSH32: "PUSH32",

    DUP1:  "DUP1",
    DUP2:  "DUP2",
    DUP3:  "DUP3",
    DUP4:  "DUP4",
    DUP5:  "DUP5",
    DUP6:  "DUP6",
    DUP7:  "DUP7",
    DUP8:  "DUP8",
    DUP9:  "DUP9",
    DUP10: "DUP10",
    DUP11: "DUP11",
    DUP12: "DUP12",
    DUP13: "DUP13",
    DUP14: "DUP14",
    DUP15: "DUP15",
    DUP16: "DUP16",

    SWAP1:  "SWAP1",
    SWAP2:  "SWAP2",
    SWAP3:  "SWAP3",
    SWAP4:  "SWAP4",
    SWAP5:  "SWAP5",
    SWAP6:  "SWAP6",
    SWAP7:  "SWAP7",
    SWAP8:  "SWAP8",
    SWAP9:  "SWAP9",
    SWAP10: "SWAP10",
    SWAP11: "SWAP11",
    SWAP12: "SWAP12",
    SWAP13: "SWAP13",
    SWAP14: "SWAP14",
    SWAP15: "SWAP15",
    SWAP16: "SWAP16",
    LOG0:   "LOG0",
    LOG1:   "LOG1",
    LOG2:   "LOG2",
    LOG3:   "LOG3",
    LOG4:   "LOG4",

    // 0xf0 range.
    CREATE:       "CREATE",
    CALL:         "CALL",
    RETURN:       "RETURN",
    CALLCODE:     "CALLCODE",
    DELEGATECALL: "DELEGATECALL",
    CREATE2:      "CREATE2",
    STATICCALL:   "STATICCALL",
    REVERT:       "REVERT",
    SELFDESTRUCT: "SELFDESTRUCT",

    PUSH: "PUSH",
    DUP:  "DUP",
    SWAP: "SWAP",
}

func (op OpCode) String() string {
    str := opCodeToString[op]
    if len(str) == 0 {
        return fmt.Sprintf("Missing opcode 0x%x", int(op))
    }

    return str
}

var stringToOp = map[string]OpCode{
    "STOP":           STOP,
    "ADD":            ADD,
    "MUL":            MUL,
    "SUB":            SUB,
    "DIV":            DIV,
    "SDIV":           SDIV,
    "MOD":            MOD,
    "SMOD":           SMOD,
    "EXP":            EXP,
    "NOT":            NOT,
    "LT":             LT,
    "GT":             GT,
    "SLT":            SLT,
    "SGT":            SGT,
    "EQ":             EQ,
    "ISZERO":         ISZERO,
    "SIGNEXTEND":     SIGNEXTEND,
    "AND":            AND,
    "OR":             OR,
    "XOR":            XOR,
    "BYTE":           BYTE,
    "SHL":            SHL,
    "SHR":            SHR,
    "SAR":            SAR,
    "ADDMOD":         ADDMOD,
    "MULMOD":         MULMOD,
    "SHA3":           SHA3,
    "RAND":           RAND,
    "ADDRESS":        ADDRESS,
    "BALANCE":        BALANCE,
    "ORIGIN":         ORIGIN,
    "CALLER":         CALLER,
    "CALLVALUE":      CALLVALUE,
    "CALLDATALOAD":   CALLDATALOAD,
    "CALLDATASIZE":   CALLDATASIZE,
    "CALLDATACOPY":   CALLDATACOPY,
    "DELEGATECALL":   DELEGATECALL,
    "STATICCALL":     STATICCALL,
    "CODESIZE":       CODESIZE,
    "CODECOPY":       CODECOPY,
    "GASPRICE":       GASPRICE,
    "EXTCODESIZE":    EXTCODESIZE,
    "EXTCODECOPY":    EXTCODECOPY,
    "RETURNDATASIZE": RETURNDATASIZE,
    "RETURNDATACOPY": RETURNDATACOPY,
    "EXTCODEHASH":    EXTCODEHASH,
    "BLOCKHASH":      BLOCKHASH,
    "COINBASE":       COINBASE,
    "TIMESTAMP":      TIMESTAMP,
    "NUMBER":         NUMBER,
    "DIFFICULTY":     DIFFICULTY,
    "GASLIMIT":       GASLIMIT,
    "POP":            POP,
    "MLOAD":          MLOAD,
    "MSTORE":         MSTORE,
    "MSTORE8":        MSTORE8,
    "SLOAD":          SLOAD,
    "SSTORE":         SSTORE,
    "JUMP":           JUMP,
    "JUMPI":          JUMPI,
    "PC":             PC,
    "MSIZE":          MSIZE,
    "GAS":            GAS,
    "JUMPDEST":       JUMPDEST,
    "PUSH1":          PUSH1,
    "PUSH2":          PUSH2,
    "PUSH3":          PUSH3,
    "PUSH4":          PUSH4,
    "PUSH5":          PUSH5,
    "PUSH6":          PUSH6,
    "PUSH7":          PUSH7,
    "PUSH8":          PUSH8,
    "PUSH9":          PUSH9,
    "PUSH10":         PUSH10,
    "PUSH11":         PUSH11,
    "PUSH12":         PUSH12,
    "PUSH13":         PUSH13,
    "PUSH14":         PUSH14,
    "PUSH15":         PUSH15,
    "PUSH16":         PUSH16,
    "PUSH17":         PUSH17,
    "PUSH18":         PUSH18,
    "PUSH19":         PUSH19,
    "PUSH20":         PUSH20,
    "PUSH21":         PUSH21,
    "PUSH22":         PUSH22,
    "PUSH23":         PUSH23,
    "PUSH24":         PUSH24,
    "PUSH25":         PUSH25,
    "PUSH26":         PUSH26,
    "PUSH27":         PUSH27,
    "PUSH28":         PUSH28,
    "PUSH29":         PUSH29,
    "PUSH30":         PUSH30,
    "PUSH31":         PUSH31,
    "PUSH32":         PUSH32,
    "DUP1":           DUP1,
    "DUP2":           DUP2,
    "DUP3":           DUP3,
    "DUP4":           DUP4,
    "DUP5":           DUP5,
    "DUP6":           DUP6,
    "DUP7":           DUP7,
    "DUP8":           DUP8,
    "DUP9":           DUP9,
    "DUP10":          DUP10,
    "DUP11":          DUP11,
    "DUP12":          DUP12,
    "DUP13":          DUP13,
    "DUP14":          DUP14,
    "DUP15":          DUP15,
    "DUP16":          DUP16,
    "SWAP1":          SWAP1,
    "SWAP2":          SWAP2,
    "SWAP3":          SWAP3,
    "SWAP4":          SWAP4,
    "SWAP5":          SWAP5,
    "SWAP6":          SWAP6,
    "SWAP7":          SWAP7,
    "SWAP8":          SWAP8,
    "SWAP9":          SWAP9,
    "SWAP10":         SWAP10,
    "SWAP11":         SWAP11,
    "SWAP12":         SWAP12,
    "SWAP13":         SWAP13,
    "SWAP14":         SWAP14,
    "SWAP15":         SWAP15,
    "SWAP16":         SWAP16,
    "LOG0":           LOG0,
    "LOG1":           LOG1,
    "LOG2":           LOG2,
    "LOG3":           LOG3,
    "LOG4":           LOG4,
    "CREATE":         CREATE,
    "CREATE2":        CREATE2,
    "CALL":           CALL,
    "RETURN":         RETURN,
    "CALLCODE":       CALLCODE,
    "REVERT":         REVERT,
    "SELFDESTRUCT":   SELFDESTRUCT,
}

// StringToOp finds the opcode whose name is stored in `str`.
func StringToOp(str string) OpCode {
    return stringToOp[str]
}