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