github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/vm/opcodes.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package vm 13 14 import ( 15 "fmt" 16 ) 17 18 // OpCode is an EVM opcode 19 type OpCode byte 20 21 func (op OpCode) IsPush() bool { 22 switch op { 23 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: 24 return true 25 } 26 return false 27 } 28 29 func (op OpCode) IsStaticJump() bool { 30 return op == JUMP 31 } 32 33 const ( 34 // 0x0 range - arithmetic ops 35 STOP OpCode = iota 36 ADD 37 MUL 38 SUB 39 DIV 40 SDIV 41 MOD 42 SMOD 43 ADDMOD 44 MULMOD 45 EXP 46 SIGNEXTEND 47 ) 48 49 const ( 50 LT OpCode = iota + 0x10 51 GT 52 SLT 53 SGT 54 EQ 55 ISZERO 56 AND 57 OR 58 XOR 59 NOT 60 BYTE 61 SHL 62 SHR 63 SAR 64 65 SHA3 = 0x20 66 ) 67 68 const ( 69 // 0x30 range - closure state 70 ADDRESS OpCode = 0x30 + iota 71 BALANCE 72 ORIGIN 73 CALLER 74 CALLVALUE 75 CALLDATALOAD 76 CALLDATASIZE 77 CALLDATACOPY 78 CODESIZE 79 CODECOPY 80 GASPRICE 81 EXTCODESIZE 82 EXTCODECOPY 83 RETURNDATASIZE 84 RETURNDATACOPY 85 ) 86 87 const ( 88 // 0x40 range - block operations 89 BLOCKHASH OpCode = 0x40 + iota 90 COINBASE 91 TIMESTAMP 92 NUMBER 93 DIFFICULTY 94 GASLIMIT 95 ) 96 97 const ( 98 // 0x50 range - 'storage' and execution 99 POP OpCode = 0x50 + iota 100 MLOAD 101 MSTORE 102 MSTORE8 103 SLOAD 104 SSTORE 105 JUMP 106 JUMPI 107 PC 108 MSIZE 109 GAS 110 JUMPDEST 111 ) 112 113 const ( 114 // 0x60 range 115 PUSH1 OpCode = 0x60 + iota 116 PUSH2 117 PUSH3 118 PUSH4 119 PUSH5 120 PUSH6 121 PUSH7 122 PUSH8 123 PUSH9 124 PUSH10 125 PUSH11 126 PUSH12 127 PUSH13 128 PUSH14 129 PUSH15 130 PUSH16 131 PUSH17 132 PUSH18 133 PUSH19 134 PUSH20 135 PUSH21 136 PUSH22 137 PUSH23 138 PUSH24 139 PUSH25 140 PUSH26 141 PUSH27 142 PUSH28 143 PUSH29 144 PUSH30 145 PUSH31 146 PUSH32 147 DUP1 148 DUP2 149 DUP3 150 DUP4 151 DUP5 152 DUP6 153 DUP7 154 DUP8 155 DUP9 156 DUP10 157 DUP11 158 DUP12 159 DUP13 160 DUP14 161 DUP15 162 DUP16 163 SWAP1 164 SWAP2 165 SWAP3 166 SWAP4 167 SWAP5 168 SWAP6 169 SWAP7 170 SWAP8 171 SWAP9 172 SWAP10 173 SWAP11 174 SWAP12 175 SWAP13 176 SWAP14 177 SWAP15 178 SWAP16 179 ) 180 181 const ( 182 LOG0 OpCode = 0xa0 + iota 183 LOG1 184 LOG2 185 LOG3 186 LOG4 187 ) 188 189 // unofficial opcodes used for parsing 190 const ( 191 PUSH OpCode = 0xb0 + iota 192 DUP 193 SWAP 194 ) 195 196 const ( 197 // 0xf0 range - closures 198 CREATE OpCode = 0xf0 + iota 199 CALL 200 CALLCODE 201 RETURN 202 DELEGATECALL 203 STATICCALL = 0xfa 204 205 REVERT = 0xfd 206 SELFDESTRUCT = 0xff 207 ) 208 209 // Since the opcodes aren't all in order we can't use a regular slice 210 var opCodeToString = map[OpCode]string{ 211 // 0x0 range - arithmetic ops 212 STOP: "STOP", 213 ADD: "ADD", 214 MUL: "MUL", 215 SUB: "SUB", 216 DIV: "DIV", 217 SDIV: "SDIV", 218 MOD: "MOD", 219 SMOD: "SMOD", 220 EXP: "EXP", 221 NOT: "NOT", 222 LT: "LT", 223 GT: "GT", 224 SLT: "SLT", 225 SGT: "SGT", 226 EQ: "EQ", 227 ISZERO: "ISZERO", 228 SIGNEXTEND: "SIGNEXTEND", 229 230 // 0x10 range - bit ops 231 AND: "AND", 232 OR: "OR", 233 XOR: "XOR", 234 BYTE: "BYTE", 235 SHL: "SHL", 236 SHR: "SHR", 237 SAR: "SAR", 238 ADDMOD: "ADDMOD", 239 MULMOD: "MULMOD", 240 241 // 0x20 range - crypto 242 SHA3: "SHA3", 243 244 // 0x30 range - closure state 245 ADDRESS: "ADDRESS", 246 BALANCE: "BALANCE", 247 ORIGIN: "ORIGIN", 248 CALLER: "CALLER", 249 CALLVALUE: "CALLVALUE", 250 CALLDATALOAD: "CALLDATALOAD", 251 CALLDATASIZE: "CALLDATASIZE", 252 CALLDATACOPY: "CALLDATACOPY", 253 CODESIZE: "CODESIZE", 254 CODECOPY: "CODECOPY", 255 GASPRICE: "GASPRICE", 256 EXTCODESIZE: "EXTCODESIZE", 257 EXTCODECOPY: "EXTCODECOPY", 258 RETURNDATASIZE: "RETURNDATASIZE", 259 RETURNDATACOPY: "RETURNDATACOPY", 260 261 // 0x40 range - block operations 262 BLOCKHASH: "BLOCKHASH", 263 COINBASE: "COINBASE", 264 TIMESTAMP: "TIMESTAMP", 265 NUMBER: "NUMBER", 266 DIFFICULTY: "DIFFICULTY", 267 GASLIMIT: "GASLIMIT", 268 269 // 0x50 range - 'storage' and execution 270 POP: "POP", 271 //DUP: "DUP", 272 //SWAP: "SWAP", 273 MLOAD: "MLOAD", 274 MSTORE: "MSTORE", 275 MSTORE8: "MSTORE8", 276 SLOAD: "SLOAD", 277 SSTORE: "SSTORE", 278 JUMP: "JUMP", 279 JUMPI: "JUMPI", 280 PC: "PC", 281 MSIZE: "MSIZE", 282 GAS: "GAS", 283 JUMPDEST: "JUMPDEST", 284 285 // 0x60 range - push 286 PUSH1: "PUSH1", 287 PUSH2: "PUSH2", 288 PUSH3: "PUSH3", 289 PUSH4: "PUSH4", 290 PUSH5: "PUSH5", 291 PUSH6: "PUSH6", 292 PUSH7: "PUSH7", 293 PUSH8: "PUSH8", 294 PUSH9: "PUSH9", 295 PUSH10: "PUSH10", 296 PUSH11: "PUSH11", 297 PUSH12: "PUSH12", 298 PUSH13: "PUSH13", 299 PUSH14: "PUSH14", 300 PUSH15: "PUSH15", 301 PUSH16: "PUSH16", 302 PUSH17: "PUSH17", 303 PUSH18: "PUSH18", 304 PUSH19: "PUSH19", 305 PUSH20: "PUSH20", 306 PUSH21: "PUSH21", 307 PUSH22: "PUSH22", 308 PUSH23: "PUSH23", 309 PUSH24: "PUSH24", 310 PUSH25: "PUSH25", 311 PUSH26: "PUSH26", 312 PUSH27: "PUSH27", 313 PUSH28: "PUSH28", 314 PUSH29: "PUSH29", 315 PUSH30: "PUSH30", 316 PUSH31: "PUSH31", 317 PUSH32: "PUSH32", 318 319 DUP1: "DUP1", 320 DUP2: "DUP2", 321 DUP3: "DUP3", 322 DUP4: "DUP4", 323 DUP5: "DUP5", 324 DUP6: "DUP6", 325 DUP7: "DUP7", 326 DUP8: "DUP8", 327 DUP9: "DUP9", 328 DUP10: "DUP10", 329 DUP11: "DUP11", 330 DUP12: "DUP12", 331 DUP13: "DUP13", 332 DUP14: "DUP14", 333 DUP15: "DUP15", 334 DUP16: "DUP16", 335 336 SWAP1: "SWAP1", 337 SWAP2: "SWAP2", 338 SWAP3: "SWAP3", 339 SWAP4: "SWAP4", 340 SWAP5: "SWAP5", 341 SWAP6: "SWAP6", 342 SWAP7: "SWAP7", 343 SWAP8: "SWAP8", 344 SWAP9: "SWAP9", 345 SWAP10: "SWAP10", 346 SWAP11: "SWAP11", 347 SWAP12: "SWAP12", 348 SWAP13: "SWAP13", 349 SWAP14: "SWAP14", 350 SWAP15: "SWAP15", 351 SWAP16: "SWAP16", 352 LOG0: "LOG0", 353 LOG1: "LOG1", 354 LOG2: "LOG2", 355 LOG3: "LOG3", 356 LOG4: "LOG4", 357 358 // 0xf0 range 359 CREATE: "CREATE", 360 CALL: "CALL", 361 RETURN: "RETURN", 362 CALLCODE: "CALLCODE", 363 DELEGATECALL: "DELEGATECALL", 364 STATICCALL: "STATICCALL", 365 REVERT: "REVERT", 366 SELFDESTRUCT: "SELFDESTRUCT", 367 368 PUSH: "PUSH", 369 DUP: "DUP", 370 SWAP: "SWAP", 371 } 372 373 func (o OpCode) String() string { 374 str := opCodeToString[o] 375 if len(str) == 0 { 376 return fmt.Sprintf("Missing opcode 0x%x", int(o)) 377 } 378 379 return str 380 } 381 382 var stringToOp = map[string]OpCode{ 383 "STOP": STOP, 384 "ADD": ADD, 385 "MUL": MUL, 386 "SUB": SUB, 387 "DIV": DIV, 388 "SDIV": SDIV, 389 "MOD": MOD, 390 "SMOD": SMOD, 391 "EXP": EXP, 392 "NOT": NOT, 393 "LT": LT, 394 "GT": GT, 395 "SLT": SLT, 396 "SGT": SGT, 397 "EQ": EQ, 398 "ISZERO": ISZERO, 399 "SIGNEXTEND": SIGNEXTEND, 400 "AND": AND, 401 "OR": OR, 402 "XOR": XOR, 403 "BYTE": BYTE, 404 "SHL": SHL, 405 "SHR": SHR, 406 "SAR": SAR, 407 "ADDMOD": ADDMOD, 408 "MULMOD": MULMOD, 409 "SHA3": SHA3, 410 "ADDRESS": ADDRESS, 411 "BALANCE": BALANCE, 412 "ORIGIN": ORIGIN, 413 "CALLER": CALLER, 414 "CALLVALUE": CALLVALUE, 415 "CALLDATALOAD": CALLDATALOAD, 416 "CALLDATASIZE": CALLDATASIZE, 417 "CALLDATACOPY": CALLDATACOPY, 418 "DELEGATECALL": DELEGATECALL, 419 "STATICCALL": STATICCALL, 420 "CODESIZE": CODESIZE, 421 "CODECOPY": CODECOPY, 422 "GASPRICE": GASPRICE, 423 "EXTCODESIZE": EXTCODESIZE, 424 "EXTCODECOPY": EXTCODECOPY, 425 "RETURNDATASIZE": RETURNDATASIZE, 426 "RETURNDATACOPY": RETURNDATACOPY, 427 "BLOCKHASH": BLOCKHASH, 428 "COINBASE": COINBASE, 429 "TIMESTAMP": TIMESTAMP, 430 "NUMBER": NUMBER, 431 "DIFFICULTY": DIFFICULTY, 432 "GASLIMIT": GASLIMIT, 433 "POP": POP, 434 "MLOAD": MLOAD, 435 "MSTORE": MSTORE, 436 "MSTORE8": MSTORE8, 437 "SLOAD": SLOAD, 438 "SSTORE": SSTORE, 439 "JUMP": JUMP, 440 "JUMPI": JUMPI, 441 "PC": PC, 442 "MSIZE": MSIZE, 443 "GAS": GAS, 444 "JUMPDEST": JUMPDEST, 445 "PUSH1": PUSH1, 446 "PUSH2": PUSH2, 447 "PUSH3": PUSH3, 448 "PUSH4": PUSH4, 449 "PUSH5": PUSH5, 450 "PUSH6": PUSH6, 451 "PUSH7": PUSH7, 452 "PUSH8": PUSH8, 453 "PUSH9": PUSH9, 454 "PUSH10": PUSH10, 455 "PUSH11": PUSH11, 456 "PUSH12": PUSH12, 457 "PUSH13": PUSH13, 458 "PUSH14": PUSH14, 459 "PUSH15": PUSH15, 460 "PUSH16": PUSH16, 461 "PUSH17": PUSH17, 462 "PUSH18": PUSH18, 463 "PUSH19": PUSH19, 464 "PUSH20": PUSH20, 465 "PUSH21": PUSH21, 466 "PUSH22": PUSH22, 467 "PUSH23": PUSH23, 468 "PUSH24": PUSH24, 469 "PUSH25": PUSH25, 470 "PUSH26": PUSH26, 471 "PUSH27": PUSH27, 472 "PUSH28": PUSH28, 473 "PUSH29": PUSH29, 474 "PUSH30": PUSH30, 475 "PUSH31": PUSH31, 476 "PUSH32": PUSH32, 477 "DUP1": DUP1, 478 "DUP2": DUP2, 479 "DUP3": DUP3, 480 "DUP4": DUP4, 481 "DUP5": DUP5, 482 "DUP6": DUP6, 483 "DUP7": DUP7, 484 "DUP8": DUP8, 485 "DUP9": DUP9, 486 "DUP10": DUP10, 487 "DUP11": DUP11, 488 "DUP12": DUP12, 489 "DUP13": DUP13, 490 "DUP14": DUP14, 491 "DUP15": DUP15, 492 "DUP16": DUP16, 493 "SWAP1": SWAP1, 494 "SWAP2": SWAP2, 495 "SWAP3": SWAP3, 496 "SWAP4": SWAP4, 497 "SWAP5": SWAP5, 498 "SWAP6": SWAP6, 499 "SWAP7": SWAP7, 500 "SWAP8": SWAP8, 501 "SWAP9": SWAP9, 502 "SWAP10": SWAP10, 503 "SWAP11": SWAP11, 504 "SWAP12": SWAP12, 505 "SWAP13": SWAP13, 506 "SWAP14": SWAP14, 507 "SWAP15": SWAP15, 508 "SWAP16": SWAP16, 509 "LOG0": LOG0, 510 "LOG1": LOG1, 511 "LOG2": LOG2, 512 "LOG3": LOG3, 513 "LOG4": LOG4, 514 "CREATE": CREATE, 515 "CALL": CALL, 516 "RETURN": RETURN, 517 "CALLCODE": CALLCODE, 518 "REVERT": REVERT, 519 "SELFDESTRUCT": SELFDESTRUCT, 520 } 521 522 func StringToOp(str string) OpCode { 523 return stringToOp[str] 524 }