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