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