github.com/datachainlab/burrow@v0.25.0/execution/evm/asm/opcodes.go (about)

     1  // Copyright 2017 Monax Industries Limited
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package asm
    16  
    17  import (
    18  	"fmt"
    19  )
    20  
    21  type OpCode byte
    22  
    23  const (
    24  	// Op codes
    25  	// 0x0 range - arithmetic ops
    26  	STOP OpCode = iota
    27  	ADD
    28  	MUL
    29  	SUB
    30  	DIV
    31  	SDIV
    32  	MOD
    33  	SMOD
    34  	ADDMOD
    35  	MULMOD
    36  	EXP
    37  	SIGNEXTEND
    38  )
    39  
    40  const (
    41  	LT OpCode = iota + 0x10
    42  	GT
    43  	SLT
    44  	SGT
    45  	EQ
    46  	ISZERO
    47  	AND
    48  	OR
    49  	XOR
    50  	NOT
    51  	BYTE
    52  	SHL
    53  	SHR
    54  	SAR
    55  
    56  	SHA3 = 0x20
    57  )
    58  
    59  const (
    60  	// 0x30 range - closure state
    61  	ADDRESS OpCode = 0x30 + iota
    62  	BALANCE
    63  	ORIGIN
    64  	CALLER
    65  	CALLVALUE
    66  	CALLDATALOAD
    67  	CALLDATASIZE
    68  	CALLDATACOPY
    69  	CODESIZE
    70  	CODECOPY
    71  	GASPRICE_DEPRECATED
    72  	EXTCODESIZE
    73  	EXTCODECOPY
    74  	RETURNDATASIZE
    75  	RETURNDATACOPY
    76  	EXTCODEHASH // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1052.md
    77  )
    78  
    79  const (
    80  	// 0x40 range - block operations
    81  	BLOCKHASH OpCode = 0x40 + iota
    82  	COINBASE
    83  	TIMESTAMP
    84  	BLOCKHEIGHT
    85  	DIFFICULTY_DEPRECATED
    86  	GASLIMIT
    87  )
    88  
    89  const (
    90  	// 0x50 range - 'storage' and execution
    91  	POP OpCode = 0x50 + iota
    92  	MLOAD
    93  	MSTORE
    94  	MSTORE8
    95  	SLOAD
    96  	SSTORE
    97  	JUMP
    98  	JUMPI
    99  	PC
   100  	MSIZE
   101  	GAS
   102  	JUMPDEST
   103  )
   104  
   105  const (
   106  	// 0x60 range
   107  	PUSH1 OpCode = 0x60 + iota
   108  	PUSH2
   109  	PUSH3
   110  	PUSH4
   111  	PUSH5
   112  	PUSH6
   113  	PUSH7
   114  	PUSH8
   115  	PUSH9
   116  	PUSH10
   117  	PUSH11
   118  	PUSH12
   119  	PUSH13
   120  	PUSH14
   121  	PUSH15
   122  	PUSH16
   123  	PUSH17
   124  	PUSH18
   125  	PUSH19
   126  	PUSH20
   127  	PUSH21
   128  	PUSH22
   129  	PUSH23
   130  	PUSH24
   131  	PUSH25
   132  	PUSH26
   133  	PUSH27
   134  	PUSH28
   135  	PUSH29
   136  	PUSH30
   137  	PUSH31
   138  	PUSH32
   139  	DUP1
   140  	DUP2
   141  	DUP3
   142  	DUP4
   143  	DUP5
   144  	DUP6
   145  	DUP7
   146  	DUP8
   147  	DUP9
   148  	DUP10
   149  	DUP11
   150  	DUP12
   151  	DUP13
   152  	DUP14
   153  	DUP15
   154  	DUP16
   155  	SWAP1
   156  	SWAP2
   157  	SWAP3
   158  	SWAP4
   159  	SWAP5
   160  	SWAP6
   161  	SWAP7
   162  	SWAP8
   163  	SWAP9
   164  	SWAP10
   165  	SWAP11
   166  	SWAP12
   167  	SWAP13
   168  	SWAP14
   169  	SWAP15
   170  	SWAP16
   171  )
   172  
   173  const (
   174  	LOG0 OpCode = 0xa0 + iota
   175  	LOG1
   176  	LOG2
   177  	LOG3
   178  	LOG4
   179  )
   180  
   181  const (
   182  	// 0xf0 range - closures
   183  	CREATE OpCode = 0xf0 + iota
   184  	CALL
   185  	CALLCODE
   186  	RETURN
   187  	DELEGATECALL
   188  
   189  	// 0x70 range - other
   190  	STATICCALL   = 0xfa
   191  	CREATE2      = 0xfb
   192  	REVERT       = 0xfd
   193  	INVALID      = 0xfe
   194  	SELFDESTRUCT = 0xff
   195  )
   196  
   197  var opCodeNames = map[OpCode]string{
   198  	// 0x0 range - arithmetic ops
   199  	STOP:       "STOP",
   200  	ADD:        "ADD",
   201  	MUL:        "MUL",
   202  	SUB:        "SUB",
   203  	DIV:        "DIV",
   204  	SDIV:       "SDIV",
   205  	MOD:        "MOD",
   206  	SMOD:       "SMOD",
   207  	EXP:        "EXP",
   208  	NOT:        "NOT",
   209  	LT:         "LT",
   210  	GT:         "GT",
   211  	SLT:        "SLT",
   212  	SGT:        "SGT",
   213  	EQ:         "EQ",
   214  	ISZERO:     "ISZERO",
   215  	SIGNEXTEND: "SIGNEXTEND",
   216  
   217  	// 0x10 range - bit ops
   218  	AND:    "AND",
   219  	OR:     "OR",
   220  	XOR:    "XOR",
   221  	BYTE:   "BYTE",
   222  	SHL:    "SHL",
   223  	SHR:    "SHR",
   224  	SAR:    "SAR",
   225  	ADDMOD: "ADDMOD",
   226  	MULMOD: "MULMOD",
   227  
   228  	// 0x20 range - crypto
   229  	SHA3: "SHA3",
   230  
   231  	// 0x30 range - closure state
   232  	ADDRESS:             "ADDRESS",
   233  	BALANCE:             "BALANCE",
   234  	ORIGIN:              "ORIGIN",
   235  	CALLER:              "CALLER",
   236  	CALLVALUE:           "CALLVALUE",
   237  	CALLDATALOAD:        "CALLDATALOAD",
   238  	CALLDATASIZE:        "CALLDATASIZE",
   239  	CALLDATACOPY:        "CALLDATACOPY",
   240  	CODESIZE:            "CODESIZE",
   241  	CODECOPY:            "CODECOPY",
   242  	GASPRICE_DEPRECATED: "TXGASPRICE_DEPRECATED",
   243  	EXTCODESIZE:         "EXTCODESIZE",
   244  	EXTCODECOPY:         "EXTCODECOPY",
   245  	RETURNDATASIZE:      "RETURNDATASIZE",
   246  	RETURNDATACOPY:      "RETURNDATACOPY",
   247  	EXTCODEHASH:         "EXTCODEHASH",
   248  
   249  	// 0x40 range - block operations
   250  	BLOCKHASH:             "BLOCKHASH",
   251  	COINBASE:              "COINBASE",
   252  	TIMESTAMP:             "TIMESTAMP",
   253  	BLOCKHEIGHT:           "BLOCKHEIGHT",
   254  	DIFFICULTY_DEPRECATED: "DIFFICULTY_DEPRECATED",
   255  	GASLIMIT:              "GASLIMIT",
   256  
   257  	// 0x50 range - 'storage' and execution
   258  	POP:      "POP",
   259  	MLOAD:    "MLOAD",
   260  	MSTORE:   "MSTORE",
   261  	MSTORE8:  "MSTORE8",
   262  	SLOAD:    "SLOAD",
   263  	SSTORE:   "SSTORE",
   264  	JUMP:     "JUMP",
   265  	JUMPI:    "JUMPI",
   266  	PC:       "PC",
   267  	MSIZE:    "MSIZE",
   268  	GAS:      "GAS",
   269  	JUMPDEST: "JUMPDEST",
   270  
   271  	// 0x60 range - push
   272  	PUSH1:  "PUSH1",
   273  	PUSH2:  "PUSH2",
   274  	PUSH3:  "PUSH3",
   275  	PUSH4:  "PUSH4",
   276  	PUSH5:  "PUSH5",
   277  	PUSH6:  "PUSH6",
   278  	PUSH7:  "PUSH7",
   279  	PUSH8:  "PUSH8",
   280  	PUSH9:  "PUSH9",
   281  	PUSH10: "PUSH10",
   282  	PUSH11: "PUSH11",
   283  	PUSH12: "PUSH12",
   284  	PUSH13: "PUSH13",
   285  	PUSH14: "PUSH14",
   286  	PUSH15: "PUSH15",
   287  	PUSH16: "PUSH16",
   288  	PUSH17: "PUSH17",
   289  	PUSH18: "PUSH18",
   290  	PUSH19: "PUSH19",
   291  	PUSH20: "PUSH20",
   292  	PUSH21: "PUSH21",
   293  	PUSH22: "PUSH22",
   294  	PUSH23: "PUSH23",
   295  	PUSH24: "PUSH24",
   296  	PUSH25: "PUSH25",
   297  	PUSH26: "PUSH26",
   298  	PUSH27: "PUSH27",
   299  	PUSH28: "PUSH28",
   300  	PUSH29: "PUSH29",
   301  	PUSH30: "PUSH30",
   302  	PUSH31: "PUSH31",
   303  	PUSH32: "PUSH32",
   304  
   305  	DUP1:  "DUP1",
   306  	DUP2:  "DUP2",
   307  	DUP3:  "DUP3",
   308  	DUP4:  "DUP4",
   309  	DUP5:  "DUP5",
   310  	DUP6:  "DUP6",
   311  	DUP7:  "DUP7",
   312  	DUP8:  "DUP8",
   313  	DUP9:  "DUP9",
   314  	DUP10: "DUP10",
   315  	DUP11: "DUP11",
   316  	DUP12: "DUP12",
   317  	DUP13: "DUP13",
   318  	DUP14: "DUP14",
   319  	DUP15: "DUP15",
   320  	DUP16: "DUP16",
   321  
   322  	SWAP1:  "SWAP1",
   323  	SWAP2:  "SWAP2",
   324  	SWAP3:  "SWAP3",
   325  	SWAP4:  "SWAP4",
   326  	SWAP5:  "SWAP5",
   327  	SWAP6:  "SWAP6",
   328  	SWAP7:  "SWAP7",
   329  	SWAP8:  "SWAP8",
   330  	SWAP9:  "SWAP9",
   331  	SWAP10: "SWAP10",
   332  	SWAP11: "SWAP11",
   333  	SWAP12: "SWAP12",
   334  	SWAP13: "SWAP13",
   335  	SWAP14: "SWAP14",
   336  	SWAP15: "SWAP15",
   337  	SWAP16: "SWAP16",
   338  	LOG0:   "LOG0",
   339  	LOG1:   "LOG1",
   340  	LOG2:   "LOG2",
   341  	LOG3:   "LOG3",
   342  	LOG4:   "LOG4",
   343  
   344  	// 0xf0 range
   345  	CREATE:       "CREATE",
   346  	CALL:         "CALL",
   347  	RETURN:       "RETURN",
   348  	CALLCODE:     "CALLCODE",
   349  	DELEGATECALL: "DELEGATECALL",
   350  	STATICCALL:   "STATICCALL",
   351  	// 0x70 range - other
   352  	CREATE2:      "CREATE2",
   353  	REVERT:       "REVERT",
   354  	INVALID:      "INVALID",
   355  	SELFDESTRUCT: "SELFDESTRUCT",
   356  }
   357  
   358  func GetOpCode(b byte) (OpCode, bool) {
   359  	op := OpCode(b)
   360  	_, isOpcode := opCodeNames[op]
   361  	return op, isOpcode
   362  
   363  }
   364  
   365  func (o OpCode) String() string {
   366  	return o.Name()
   367  }
   368  
   369  func (o OpCode) Name() string {
   370  	str := opCodeNames[o]
   371  	if len(str) == 0 {
   372  		return fmt.Sprintf("Non-opcode 0x%x", int(o))
   373  	}
   374  
   375  	return str
   376  }
   377  
   378  // If OpCode is a Push<N> returns the number of bytes pushed (between 1 and 32 inclusive)
   379  func (o OpCode) Pushes() int {
   380  	if o >= PUSH1 && o <= PUSH32 {
   381  		return int(o - PUSH1 + 1)
   382  	}
   383  	return 0
   384  }