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