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