github.com/amazechain/amc@v0.1.3/internal/vm/jump_table.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package vm 18 19 import ( 20 "fmt" 21 "github.com/amazechain/amc/internal/vm/stack" 22 "github.com/amazechain/amc/params" 23 ) 24 25 type ( 26 executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) 27 gasFunc func(VMInterpreter, *Contract, *stack.Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 28 // memorySizeFunc returns the required size, and whether the operation overflowed a uint64 29 memorySizeFunc func(*stack.Stack) (size uint64, overflow bool) 30 ) 31 32 type operation struct { 33 // execute is the operation function 34 execute executionFunc 35 constantGas uint64 36 dynamicGas gasFunc 37 // maxStack specifies the max length the stack can have for this operation 38 // to not overflow the stack. 39 maxStack int 40 41 // numPop tells how many stack items are required 42 numPop int // δ in the Yellow Paper 43 numPush int // α in the Yellow Paper 44 isPush bool 45 isSwap bool 46 isDup bool 47 opNum int // only for push, swap, dup 48 // memorySize returns the memory size required for the operation 49 memorySize memorySizeFunc 50 } 51 52 var ( 53 frontierInstructionSet = newFrontierInstructionSet() 54 homesteadInstructionSet = newHomesteadInstructionSet() 55 tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet() 56 spuriousDragonInstructionSet = newSpuriousDragonInstructionSet() 57 byzantiumInstructionSet = newByzantiumInstructionSet() 58 constantinopleInstructionSet = newConstantinopleInstructionSet() 59 istanbulInstructionSet = newIstanbulInstructionSet() 60 berlinInstructionSet = newBerlinInstructionSet() 61 londonInstructionSet = newLondonInstructionSet() 62 shanghaiInstructionSet = newShanghaiInstructionSet() 63 cancunInstructionSet = newCancunInstructionSet() 64 pragueInstructionSet = newPragueInstructionSet() 65 ) 66 67 // JumpTable contains the EVM opcodes supported at a given fork. 68 type JumpTable [256]*operation 69 70 func validateAndFillMaxStack(jt *JumpTable) { 71 for i, op := range jt { 72 if op == nil { 73 panic(fmt.Sprintf("op 0x%x is not set", i)) 74 } 75 // The interpreter has an assumption that if the memorySize function is 76 // set, then the dynamicGas function is also set. This is a somewhat 77 // arbitrary assumption, and can be removed if we need to -- but it 78 // allows us to avoid a condition check. As long as we have that assumption 79 // in there, this little sanity check prevents us from merging in a 80 // change which violates it. 81 if op.memorySize != nil && op.dynamicGas == nil { 82 panic(fmt.Sprintf("op %v has dynamic memory but not dynamic gas", OpCode(i).String())) 83 } 84 op.maxStack = maxStack(op.numPop, op.numPush) 85 } 86 } 87 88 // newPragueInstructionSet returns the frontier, homestead, byzantium, 89 // constantinople, istanbul, petersburg, berlin, london, paris, shanghai, 90 // cancun, and prague instructions. 91 func newPragueInstructionSet() JumpTable { 92 instructionSet := newCancunInstructionSet() 93 validateAndFillMaxStack(&instructionSet) 94 return instructionSet 95 } 96 97 // newCancunInstructionSet returns the frontier, homestead, byzantium, 98 // constantinople, istanbul, petersburg, berlin, london, paris, shanghai, 99 // and cancun instructions. 100 func newCancunInstructionSet() JumpTable { 101 instructionSet := newShanghaiInstructionSet() 102 validateAndFillMaxStack(&instructionSet) 103 return instructionSet 104 } 105 106 // newShanghaiInstructionSet returns the frontier, homestead, byzantium, 107 // constantinople, istanbul, petersburg, berlin, london, paris, and shanghai instructions. 108 func newShanghaiInstructionSet() JumpTable { 109 instructionSet := newLondonInstructionSet() 110 enable3855(&instructionSet) // PUSH0 instruction https://eips.ethereum.org/EIPS/eip-3855 111 enable3860(&instructionSet) // Limit and meter initcode https://eips.ethereum.org/EIPS/eip-3860 112 validateAndFillMaxStack(&instructionSet) 113 return instructionSet 114 } 115 116 // newLondonInstructionSet returns the frontier, homestead, byzantium, 117 // constantinople, istanbul, petersburg, berlin, and london instructions. 118 func newLondonInstructionSet() JumpTable { 119 instructionSet := newBerlinInstructionSet() 120 enable3529(&instructionSet) // Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 121 enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 122 validateAndFillMaxStack(&instructionSet) 123 return instructionSet 124 } 125 126 // newBerlinInstructionSet returns the frontier, homestead, byzantium, 127 // constantinople, istanbul, petersburg and berlin instructions. 128 func newBerlinInstructionSet() JumpTable { 129 instructionSet := newIstanbulInstructionSet() 130 enable2929(&instructionSet) // Access lists for trie accesses https://eips.ethereum.org/EIPS/eip-2929 131 validateAndFillMaxStack(&instructionSet) 132 return instructionSet 133 } 134 135 // newIstanbulInstructionSet returns the frontier, homestead, byzantium, 136 // constantinople, istanbul and petersburg instructions. 137 func newIstanbulInstructionSet() JumpTable { 138 instructionSet := newConstantinopleInstructionSet() 139 140 enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344 141 enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 142 enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 143 144 validateAndFillMaxStack(&instructionSet) 145 return instructionSet 146 } 147 148 // newConstantinopleInstructionSet returns the frontier, homestead, 149 // byzantium and constantinople instructions. 150 func newConstantinopleInstructionSet() JumpTable { 151 instructionSet := newByzantiumInstructionSet() 152 instructionSet[SHL] = &operation{ 153 execute: opSHL, 154 constantGas: GasFastestStep, 155 numPop: 2, 156 numPush: 1, 157 } 158 instructionSet[SHR] = &operation{ 159 execute: opSHR, 160 constantGas: GasFastestStep, 161 numPop: 2, 162 numPush: 1, 163 } 164 instructionSet[SAR] = &operation{ 165 execute: opSAR, 166 constantGas: GasFastestStep, 167 numPop: 2, 168 numPush: 1, 169 } 170 instructionSet[EXTCODEHASH] = &operation{ 171 execute: opExtCodeHash, 172 constantGas: params.ExtcodeHashGasConstantinople, 173 numPop: 1, 174 numPush: 1, 175 } 176 instructionSet[CREATE2] = &operation{ 177 execute: opCreate2, 178 constantGas: params.Create2Gas, 179 dynamicGas: gasCreate2, 180 numPop: 4, 181 numPush: 1, 182 memorySize: memoryCreate2, 183 } 184 validateAndFillMaxStack(&instructionSet) 185 return instructionSet 186 } 187 188 // newByzantiumInstructionSet returns the frontier, homestead and 189 // byzantium instructions. 190 func newByzantiumInstructionSet() JumpTable { 191 instructionSet := newSpuriousDragonInstructionSet() 192 instructionSet[STATICCALL] = &operation{ 193 execute: opStaticCall, 194 constantGas: params.CallGasEIP150, 195 dynamicGas: gasStaticCall, 196 numPop: 6, 197 numPush: 1, 198 memorySize: memoryStaticCall, 199 } 200 instructionSet[RETURNDATASIZE] = &operation{ 201 execute: opReturnDataSize, 202 constantGas: GasQuickStep, 203 numPop: 0, 204 numPush: 1, 205 } 206 instructionSet[RETURNDATACOPY] = &operation{ 207 execute: opReturnDataCopy, 208 constantGas: GasFastestStep, 209 dynamicGas: gasReturnDataCopy, 210 numPop: 3, 211 numPush: 0, 212 memorySize: memoryReturnDataCopy, 213 } 214 instructionSet[REVERT] = &operation{ 215 execute: opRevert, 216 dynamicGas: gasRevert, 217 numPop: 2, 218 numPush: 0, 219 memorySize: memoryRevert, 220 } 221 validateAndFillMaxStack(&instructionSet) 222 return instructionSet 223 } 224 225 // EIP 158 a.k.a Spurious Dragon 226 func newSpuriousDragonInstructionSet() JumpTable { 227 instructionSet := newTangerineWhistleInstructionSet() 228 instructionSet[EXP].dynamicGas = gasExpEIP160 229 validateAndFillMaxStack(&instructionSet) 230 return instructionSet 231 232 } 233 234 // EIP 150 a.k.a Tangerine Whistle 235 func newTangerineWhistleInstructionSet() JumpTable { 236 instructionSet := newHomesteadInstructionSet() 237 instructionSet[BALANCE].constantGas = params.BalanceGasEIP150 238 instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150 239 instructionSet[SLOAD].constantGas = params.SloadGasEIP150 240 instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150 241 instructionSet[CALL].constantGas = params.CallGasEIP150 242 instructionSet[CALLCODE].constantGas = params.CallGasEIP150 243 instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150 244 validateAndFillMaxStack(&instructionSet) 245 return instructionSet 246 } 247 248 // newHomesteadInstructionSet returns the frontier and homestead 249 // instructions that can be executed during the homestead phase. 250 func newHomesteadInstructionSet() JumpTable { 251 instructionSet := newFrontierInstructionSet() 252 instructionSet[DELEGATECALL] = &operation{ 253 execute: opDelegateCall, 254 dynamicGas: gasDelegateCall, 255 constantGas: params.CallGasFrontier, 256 numPop: 6, 257 numPush: 1, 258 memorySize: memoryDelegateCall, 259 } 260 validateAndFillMaxStack(&instructionSet) 261 return instructionSet 262 } 263 264 // newFrontierInstructionSet returns the frontier instructions 265 // that can be executed during the frontier phase. 266 func newFrontierInstructionSet() JumpTable { 267 tbl := JumpTable{ 268 STOP: { 269 execute: opStop, 270 constantGas: 0, 271 numPop: 0, 272 numPush: 0, 273 }, 274 ADD: { 275 execute: opAdd, 276 constantGas: GasFastestStep, 277 numPop: 2, 278 numPush: 1, 279 }, 280 MUL: { 281 execute: opMul, 282 constantGas: GasFastStep, 283 numPop: 2, 284 numPush: 1, 285 }, 286 SUB: { 287 execute: opSub, 288 constantGas: GasFastestStep, 289 numPop: 2, 290 numPush: 1, 291 }, 292 DIV: { 293 execute: opDiv, 294 constantGas: GasFastStep, 295 numPop: 2, 296 numPush: 1, 297 }, 298 SDIV: { 299 execute: opSdiv, 300 constantGas: GasFastStep, 301 numPop: 2, 302 numPush: 1, 303 }, 304 MOD: { 305 execute: opMod, 306 constantGas: GasFastStep, 307 numPop: 2, 308 numPush: 1, 309 }, 310 SMOD: { 311 execute: opSmod, 312 constantGas: GasFastStep, 313 numPop: 2, 314 numPush: 1, 315 }, 316 ADDMOD: { 317 execute: opAddmod, 318 constantGas: GasMidStep, 319 numPop: 3, 320 numPush: 1, 321 }, 322 MULMOD: { 323 execute: opMulmod, 324 constantGas: GasMidStep, 325 numPop: 3, 326 numPush: 1, 327 }, 328 EXP: { 329 execute: opExp, 330 dynamicGas: gasExpFrontier, 331 numPop: 2, 332 numPush: 1, 333 }, 334 SIGNEXTEND: { 335 execute: opSignExtend, 336 constantGas: GasFastStep, 337 numPop: 2, 338 numPush: 1, 339 }, 340 LT: { 341 execute: opLt, 342 constantGas: GasFastestStep, 343 numPop: 2, 344 numPush: 1, 345 }, 346 GT: { 347 execute: opGt, 348 constantGas: GasFastestStep, 349 numPop: 2, 350 numPush: 1, 351 }, 352 SLT: { 353 execute: opSlt, 354 constantGas: GasFastestStep, 355 numPop: 2, 356 numPush: 1, 357 }, 358 SGT: { 359 execute: opSgt, 360 constantGas: GasFastestStep, 361 numPop: 2, 362 numPush: 1, 363 }, 364 EQ: { 365 execute: opEq, 366 constantGas: GasFastestStep, 367 numPop: 2, 368 numPush: 1, 369 }, 370 ISZERO: { 371 execute: opIszero, 372 constantGas: GasFastestStep, 373 numPop: 1, 374 numPush: 1, 375 }, 376 AND: { 377 execute: opAnd, 378 constantGas: GasFastestStep, 379 numPop: 2, 380 numPush: 1, 381 }, 382 XOR: { 383 execute: opXor, 384 constantGas: GasFastestStep, 385 numPop: 2, 386 numPush: 1, 387 }, 388 OR: { 389 execute: opOr, 390 constantGas: GasFastestStep, 391 numPop: 2, 392 numPush: 1, 393 }, 394 NOT: { 395 execute: opNot, 396 constantGas: GasFastestStep, 397 numPop: 1, 398 numPush: 1, 399 }, 400 BYTE: { 401 execute: opByte, 402 constantGas: GasFastestStep, 403 numPop: 2, 404 numPush: 1, 405 }, 406 KECCAK256: { 407 execute: opKeccak256, 408 constantGas: params.Keccak256Gas, 409 dynamicGas: gasKeccak256, 410 numPop: 2, 411 numPush: 1, 412 memorySize: memoryKeccak256, 413 }, 414 ADDRESS: { 415 execute: opAddress, 416 constantGas: GasQuickStep, 417 numPop: 0, 418 numPush: 1, 419 }, 420 BALANCE: { 421 execute: opBalance, 422 constantGas: params.BalanceGasFrontier, 423 numPop: 1, 424 numPush: 1, 425 }, 426 ORIGIN: { 427 execute: opOrigin, 428 constantGas: GasQuickStep, 429 numPop: 0, 430 numPush: 1, 431 }, 432 CALLER: { 433 execute: opCaller, 434 constantGas: GasQuickStep, 435 numPop: 0, 436 numPush: 1, 437 }, 438 CALLVALUE: { 439 execute: opCallValue, 440 constantGas: GasQuickStep, 441 numPop: 0, 442 numPush: 1, 443 }, 444 CALLDATALOAD: { 445 execute: opCallDataLoad, 446 constantGas: GasFastestStep, 447 numPop: 1, 448 numPush: 1, 449 }, 450 CALLDATASIZE: { 451 execute: opCallDataSize, 452 constantGas: GasQuickStep, 453 numPop: 0, 454 numPush: 1, 455 }, 456 CALLDATACOPY: { 457 execute: opCallDataCopy, 458 constantGas: GasFastestStep, 459 dynamicGas: gasCallDataCopy, 460 numPop: 3, 461 numPush: 0, 462 memorySize: memoryCallDataCopy, 463 }, 464 CODESIZE: { 465 execute: opCodeSize, 466 constantGas: GasQuickStep, 467 numPop: 0, 468 numPush: 1, 469 }, 470 CODECOPY: { 471 execute: opCodeCopy, 472 constantGas: GasFastestStep, 473 dynamicGas: gasCodeCopy, 474 numPop: 3, 475 numPush: 0, 476 memorySize: memoryCodeCopy, 477 }, 478 GASPRICE: { 479 execute: opGasprice, 480 constantGas: GasQuickStep, 481 numPop: 0, 482 numPush: 1, 483 }, 484 EXTCODESIZE: { 485 execute: opExtCodeSize, 486 constantGas: params.ExtcodeSizeGasFrontier, 487 numPop: 1, 488 numPush: 1, 489 }, 490 EXTCODECOPY: { 491 execute: opExtCodeCopy, 492 constantGas: params.ExtcodeCopyBaseFrontier, 493 dynamicGas: gasExtCodeCopy, 494 numPop: 4, 495 numPush: 0, 496 memorySize: memoryExtCodeCopy, 497 }, 498 BLOCKHASH: { 499 execute: opBlockhash, 500 constantGas: GasExtStep, 501 numPop: 1, 502 numPush: 1, 503 }, 504 COINBASE: { 505 execute: opCoinbase, 506 constantGas: GasQuickStep, 507 numPop: 0, 508 numPush: 1, 509 }, 510 TIMESTAMP: { 511 execute: opTimestamp, 512 constantGas: GasQuickStep, 513 numPop: 0, 514 numPush: 1, 515 }, 516 NUMBER: { 517 execute: opNumber, 518 constantGas: GasQuickStep, 519 numPop: 0, 520 numPush: 1, 521 }, 522 DIFFICULTY: { 523 execute: opDifficulty, 524 constantGas: GasQuickStep, 525 numPop: 0, 526 numPush: 1, 527 }, 528 GASLIMIT: { 529 execute: opGasLimit, 530 constantGas: GasQuickStep, 531 numPop: 0, 532 numPush: 1, 533 }, 534 POP: { 535 execute: opPop, 536 constantGas: GasQuickStep, 537 numPop: 1, 538 numPush: 0, 539 }, 540 MLOAD: { 541 execute: opMload, 542 constantGas: GasFastestStep, 543 dynamicGas: gasMLoad, 544 numPop: 1, 545 numPush: 1, 546 memorySize: memoryMLoad, 547 }, 548 MSTORE: { 549 execute: opMstore, 550 constantGas: GasFastestStep, 551 dynamicGas: gasMStore, 552 numPop: 2, 553 numPush: 0, 554 memorySize: memoryMStore, 555 }, 556 MSTORE8: { 557 execute: opMstore8, 558 constantGas: GasFastestStep, 559 dynamicGas: gasMStore8, 560 memorySize: memoryMStore8, 561 numPop: 2, 562 numPush: 0, 563 }, 564 SLOAD: { 565 execute: opSload, 566 constantGas: params.SloadGasFrontier, 567 numPop: 1, 568 numPush: 1, 569 }, 570 SSTORE: { 571 execute: opSstore, 572 dynamicGas: gasSStore, 573 numPop: 2, 574 numPush: 0, 575 }, 576 JUMP: { 577 execute: opJump, 578 constantGas: GasMidStep, 579 numPop: 1, 580 numPush: 0, 581 }, 582 JUMPI: { 583 execute: opJumpi, 584 constantGas: GasSlowStep, 585 numPop: 2, 586 numPush: 0, 587 }, 588 PC: { 589 execute: opPc, 590 constantGas: GasQuickStep, 591 numPop: 0, 592 numPush: 1, 593 }, 594 MSIZE: { 595 execute: opMsize, 596 constantGas: GasQuickStep, 597 numPop: 0, 598 numPush: 1, 599 }, 600 GAS: { 601 execute: opGas, 602 constantGas: GasQuickStep, 603 numPop: 0, 604 numPush: 1, 605 }, 606 JUMPDEST: { 607 execute: opJumpdest, 608 constantGas: params.JumpdestGas, 609 numPop: 0, 610 numPush: 0, 611 }, 612 PUSH1: { 613 execute: opPush1, 614 constantGas: GasFastestStep, 615 numPop: 0, 616 numPush: 1, 617 isPush: true, 618 opNum: 1, 619 }, 620 PUSH2: { 621 execute: makePush(2, 2), 622 constantGas: GasFastestStep, 623 numPop: 0, 624 numPush: 1, 625 isPush: true, 626 opNum: 2, 627 }, 628 PUSH3: { 629 execute: makePush(3, 3), 630 constantGas: GasFastestStep, 631 numPop: 0, 632 numPush: 1, 633 isPush: true, 634 opNum: 3, 635 }, 636 PUSH4: { 637 execute: makePush(4, 4), 638 constantGas: GasFastestStep, 639 numPop: 0, 640 numPush: 1, 641 isPush: true, 642 opNum: 4, 643 }, 644 PUSH5: { 645 execute: makePush(5, 5), 646 constantGas: GasFastestStep, 647 numPop: 0, 648 numPush: 1, 649 isPush: true, 650 opNum: 5, 651 }, 652 PUSH6: { 653 execute: makePush(6, 6), 654 constantGas: GasFastestStep, 655 numPop: 0, 656 numPush: 1, 657 isPush: true, 658 opNum: 6, 659 }, 660 PUSH7: { 661 execute: makePush(7, 7), 662 constantGas: GasFastestStep, 663 numPop: 0, 664 numPush: 1, 665 isPush: true, 666 opNum: 7, 667 }, 668 PUSH8: { 669 execute: makePush(8, 8), 670 constantGas: GasFastestStep, 671 numPop: 0, 672 numPush: 1, 673 isPush: true, 674 opNum: 8, 675 }, 676 PUSH9: { 677 execute: makePush(9, 9), 678 constantGas: GasFastestStep, 679 numPop: 0, 680 numPush: 1, 681 isPush: true, 682 opNum: 9, 683 }, 684 PUSH10: { 685 execute: makePush(10, 10), 686 constantGas: GasFastestStep, 687 numPop: 0, 688 numPush: 1, 689 isPush: true, 690 opNum: 10, 691 }, 692 PUSH11: { 693 execute: makePush(11, 11), 694 constantGas: GasFastestStep, 695 numPop: 0, 696 numPush: 1, 697 isPush: true, 698 opNum: 11, 699 }, 700 PUSH12: { 701 execute: makePush(12, 12), 702 constantGas: GasFastestStep, 703 numPop: 0, 704 numPush: 1, 705 isPush: true, 706 opNum: 12, 707 }, 708 PUSH13: { 709 execute: makePush(13, 13), 710 constantGas: GasFastestStep, 711 numPop: 0, 712 numPush: 1, 713 isPush: true, 714 opNum: 13, 715 }, 716 PUSH14: { 717 execute: makePush(14, 14), 718 constantGas: GasFastestStep, 719 numPop: 0, 720 numPush: 1, 721 isPush: true, 722 opNum: 14, 723 }, 724 PUSH15: { 725 execute: makePush(15, 15), 726 constantGas: GasFastestStep, 727 numPop: 0, 728 numPush: 1, 729 isPush: true, 730 opNum: 15, 731 }, 732 PUSH16: { 733 execute: makePush(16, 16), 734 constantGas: GasFastestStep, 735 numPop: 0, 736 numPush: 1, 737 isPush: true, 738 opNum: 16, 739 }, 740 PUSH17: { 741 execute: makePush(17, 17), 742 constantGas: GasFastestStep, 743 numPop: 0, 744 numPush: 1, 745 isPush: true, 746 opNum: 17, 747 }, 748 PUSH18: { 749 execute: makePush(18, 18), 750 constantGas: GasFastestStep, 751 numPop: 0, 752 numPush: 1, 753 isPush: true, 754 opNum: 18, 755 }, 756 PUSH19: { 757 execute: makePush(19, 19), 758 constantGas: GasFastestStep, 759 numPop: 0, 760 numPush: 1, 761 isPush: true, 762 opNum: 19, 763 }, 764 PUSH20: { 765 execute: makePush(20, 20), 766 constantGas: GasFastestStep, 767 numPop: 0, 768 numPush: 1, 769 isPush: true, 770 opNum: 20, 771 }, 772 PUSH21: { 773 execute: makePush(21, 21), 774 constantGas: GasFastestStep, 775 numPop: 0, 776 numPush: 1, 777 isPush: true, 778 opNum: 21, 779 }, 780 PUSH22: { 781 execute: makePush(22, 22), 782 constantGas: GasFastestStep, 783 numPop: 0, 784 numPush: 1, 785 isPush: true, 786 opNum: 22, 787 }, 788 PUSH23: { 789 execute: makePush(23, 23), 790 constantGas: GasFastestStep, 791 numPop: 0, 792 numPush: 1, 793 isPush: true, 794 opNum: 23, 795 }, 796 PUSH24: { 797 execute: makePush(24, 24), 798 constantGas: GasFastestStep, 799 numPop: 0, 800 numPush: 1, 801 isPush: true, 802 opNum: 24, 803 }, 804 PUSH25: { 805 execute: makePush(25, 25), 806 constantGas: GasFastestStep, 807 numPop: 0, 808 numPush: 1, 809 isPush: true, 810 opNum: 25, 811 }, 812 PUSH26: { 813 execute: makePush(26, 26), 814 constantGas: GasFastestStep, 815 numPop: 0, 816 numPush: 1, 817 isPush: true, 818 opNum: 26, 819 }, 820 PUSH27: { 821 execute: makePush(27, 27), 822 constantGas: GasFastestStep, 823 numPop: 0, 824 numPush: 1, 825 isPush: true, 826 opNum: 27, 827 }, 828 PUSH28: { 829 execute: makePush(28, 28), 830 constantGas: GasFastestStep, 831 numPop: 0, 832 numPush: 1, 833 isPush: true, 834 opNum: 28, 835 }, 836 PUSH29: { 837 execute: makePush(29, 29), 838 constantGas: GasFastestStep, 839 numPop: 0, 840 numPush: 1, 841 isPush: true, 842 opNum: 29, 843 }, 844 PUSH30: { 845 execute: makePush(30, 30), 846 constantGas: GasFastestStep, 847 numPop: 0, 848 numPush: 1, 849 isPush: true, 850 opNum: 30, 851 }, 852 PUSH31: { 853 execute: makePush(31, 31), 854 constantGas: GasFastestStep, 855 numPop: 0, 856 numPush: 1, 857 isPush: true, 858 opNum: 31, 859 }, 860 PUSH32: { 861 execute: makePush(32, 32), 862 constantGas: GasFastestStep, 863 numPop: 0, 864 numPush: 1, 865 isPush: true, 866 opNum: 32, 867 }, 868 DUP1: { 869 execute: makeDup(1), 870 constantGas: GasFastestStep, 871 numPop: 1, 872 numPush: 2, 873 isDup: true, 874 opNum: 1, 875 }, 876 DUP2: { 877 execute: makeDup(2), 878 constantGas: GasFastestStep, 879 numPop: 2, 880 numPush: 3, 881 isDup: true, 882 opNum: 2, 883 }, 884 DUP3: { 885 execute: makeDup(3), 886 constantGas: GasFastestStep, 887 numPop: 3, 888 numPush: 4, 889 isDup: true, 890 opNum: 3, 891 }, 892 DUP4: { 893 execute: makeDup(4), 894 constantGas: GasFastestStep, 895 numPop: 4, 896 numPush: 5, 897 isDup: true, 898 opNum: 4, 899 }, 900 DUP5: { 901 execute: makeDup(5), 902 constantGas: GasFastestStep, 903 numPop: 5, 904 numPush: 6, 905 isDup: true, 906 opNum: 5, 907 }, 908 DUP6: { 909 execute: makeDup(6), 910 constantGas: GasFastestStep, 911 numPop: 6, 912 numPush: 7, 913 isDup: true, 914 opNum: 6, 915 }, 916 DUP7: { 917 execute: makeDup(7), 918 constantGas: GasFastestStep, 919 numPop: 7, 920 numPush: 8, 921 isDup: true, 922 opNum: 7, 923 }, 924 DUP8: { 925 execute: makeDup(8), 926 constantGas: GasFastestStep, 927 numPop: 8, 928 numPush: 9, 929 isDup: true, 930 opNum: 8, 931 }, 932 DUP9: { 933 execute: makeDup(9), 934 constantGas: GasFastestStep, 935 numPop: 9, 936 numPush: 10, 937 isDup: true, 938 opNum: 9, 939 }, 940 DUP10: { 941 execute: makeDup(10), 942 constantGas: GasFastestStep, 943 numPop: 10, 944 numPush: 11, 945 isDup: true, 946 opNum: 10, 947 }, 948 DUP11: { 949 execute: makeDup(11), 950 constantGas: GasFastestStep, 951 numPop: 11, 952 numPush: 12, 953 isDup: true, 954 opNum: 11, 955 }, 956 DUP12: { 957 execute: makeDup(12), 958 constantGas: GasFastestStep, 959 numPop: 12, 960 numPush: 13, 961 isDup: true, 962 opNum: 12, 963 }, 964 DUP13: { 965 execute: makeDup(13), 966 constantGas: GasFastestStep, 967 numPop: 13, 968 numPush: 14, 969 isDup: true, 970 opNum: 13, 971 }, 972 DUP14: { 973 execute: makeDup(14), 974 constantGas: GasFastestStep, 975 numPop: 14, 976 numPush: 15, 977 isDup: true, 978 opNum: 14, 979 }, 980 DUP15: { 981 execute: makeDup(15), 982 constantGas: GasFastestStep, 983 numPop: 15, 984 numPush: 16, 985 isDup: true, 986 opNum: 15, 987 }, 988 DUP16: { 989 execute: makeDup(16), 990 constantGas: GasFastestStep, 991 numPop: 16, 992 numPush: 17, 993 isDup: true, 994 opNum: 16, 995 }, 996 SWAP1: { 997 execute: makeSwap(1), 998 constantGas: GasFastestStep, 999 numPop: 2, 1000 numPush: 2, 1001 isSwap: true, 1002 opNum: 1, 1003 }, 1004 SWAP2: { 1005 execute: makeSwap(2), 1006 constantGas: GasFastestStep, 1007 numPop: 3, 1008 numPush: 3, 1009 isSwap: true, 1010 opNum: 2, 1011 }, 1012 SWAP3: { 1013 execute: makeSwap(3), 1014 constantGas: GasFastestStep, 1015 numPop: 4, 1016 numPush: 4, 1017 isSwap: true, 1018 opNum: 3, 1019 }, 1020 SWAP4: { 1021 execute: makeSwap(4), 1022 constantGas: GasFastestStep, 1023 numPop: 5, 1024 numPush: 5, 1025 isSwap: true, 1026 opNum: 4, 1027 }, 1028 SWAP5: { 1029 execute: makeSwap(5), 1030 constantGas: GasFastestStep, 1031 numPop: 6, 1032 numPush: 6, 1033 isSwap: true, 1034 opNum: 5, 1035 }, 1036 SWAP6: { 1037 execute: makeSwap(6), 1038 constantGas: GasFastestStep, 1039 numPop: 7, 1040 numPush: 7, 1041 isSwap: true, 1042 opNum: 6, 1043 }, 1044 SWAP7: { 1045 execute: makeSwap(7), 1046 constantGas: GasFastestStep, 1047 numPop: 8, 1048 numPush: 8, 1049 isSwap: true, 1050 opNum: 7, 1051 }, 1052 SWAP8: { 1053 execute: makeSwap(8), 1054 constantGas: GasFastestStep, 1055 numPop: 9, 1056 numPush: 9, 1057 isSwap: true, 1058 opNum: 8, 1059 }, 1060 SWAP9: { 1061 execute: makeSwap(9), 1062 constantGas: GasFastestStep, 1063 numPop: 10, 1064 numPush: 10, 1065 isSwap: true, 1066 opNum: 9, 1067 }, 1068 SWAP10: { 1069 execute: makeSwap(10), 1070 constantGas: GasFastestStep, 1071 numPop: 11, 1072 numPush: 11, 1073 isSwap: true, 1074 opNum: 10, 1075 }, 1076 SWAP11: { 1077 execute: makeSwap(11), 1078 constantGas: GasFastestStep, 1079 numPop: 12, 1080 numPush: 12, 1081 isSwap: true, 1082 opNum: 11, 1083 }, 1084 SWAP12: { 1085 execute: makeSwap(12), 1086 constantGas: GasFastestStep, 1087 numPop: 13, 1088 numPush: 13, 1089 isSwap: true, 1090 opNum: 12, 1091 }, 1092 SWAP13: { 1093 execute: makeSwap(13), 1094 constantGas: GasFastestStep, 1095 numPop: 14, 1096 numPush: 14, 1097 isSwap: true, 1098 opNum: 13, 1099 }, 1100 SWAP14: { 1101 execute: makeSwap(14), 1102 constantGas: GasFastestStep, 1103 numPop: 15, 1104 numPush: 15, 1105 isSwap: true, 1106 opNum: 14, 1107 }, 1108 SWAP15: { 1109 execute: makeSwap(15), 1110 constantGas: GasFastestStep, 1111 numPop: 16, 1112 numPush: 16, 1113 isSwap: true, 1114 opNum: 15, 1115 }, 1116 SWAP16: { 1117 execute: makeSwap(16), 1118 constantGas: GasFastestStep, 1119 numPop: 17, 1120 numPush: 17, 1121 isSwap: true, 1122 opNum: 16, 1123 }, 1124 LOG0: { 1125 execute: makeLog(0), 1126 dynamicGas: makeGasLog(0), 1127 numPop: 2, 1128 numPush: 0, 1129 memorySize: memoryLog, 1130 }, 1131 LOG1: { 1132 execute: makeLog(1), 1133 dynamicGas: makeGasLog(1), 1134 numPop: 3, 1135 numPush: 0, 1136 memorySize: memoryLog, 1137 }, 1138 LOG2: { 1139 execute: makeLog(2), 1140 dynamicGas: makeGasLog(2), 1141 numPop: 4, 1142 numPush: 0, 1143 memorySize: memoryLog, 1144 }, 1145 LOG3: { 1146 execute: makeLog(3), 1147 dynamicGas: makeGasLog(3), 1148 numPop: 5, 1149 numPush: 0, 1150 memorySize: memoryLog, 1151 }, 1152 LOG4: { 1153 execute: makeLog(4), 1154 dynamicGas: makeGasLog(4), 1155 numPop: 6, 1156 numPush: 0, 1157 memorySize: memoryLog, 1158 }, 1159 CREATE: { 1160 execute: opCreate, 1161 constantGas: params.CreateGas, 1162 dynamicGas: gasCreate, 1163 numPop: 3, 1164 numPush: 1, 1165 memorySize: memoryCreate, 1166 }, 1167 CALL: { 1168 execute: opCall, 1169 constantGas: params.CallGasFrontier, 1170 dynamicGas: gasCall, 1171 numPop: 7, 1172 numPush: 1, 1173 memorySize: memoryCall, 1174 }, 1175 CALLCODE: { 1176 execute: opCallCode, 1177 constantGas: params.CallGasFrontier, 1178 dynamicGas: gasCallCode, 1179 numPop: 7, 1180 numPush: 1, 1181 memorySize: memoryCall, 1182 }, 1183 RETURN: { 1184 execute: opReturn, 1185 dynamicGas: gasReturn, 1186 numPop: 2, 1187 numPush: 0, 1188 memorySize: memoryReturn, 1189 }, 1190 SELFDESTRUCT: { 1191 execute: opSelfdestruct, 1192 dynamicGas: gasSelfdestruct, 1193 numPop: 1, 1194 numPush: 0, 1195 }, 1196 } 1197 1198 // Fill all unassigned slots with opUndefined. 1199 for i, entry := range tbl { 1200 if entry == nil { 1201 tbl[i] = &operation{execute: opUndefined} 1202 } 1203 } 1204 1205 validateAndFillMaxStack(&tbl) 1206 return tbl 1207 }