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