github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/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 ) 61 62 // JumpTable contains the EVM opcodes supported at a given fork. 63 type JumpTable [256]*operation 64 65 func validate(jt JumpTable) JumpTable { 66 for i, op := range jt { 67 if op == nil { 68 panic(fmt.Sprintf("op %#x is not set", i)) 69 } 70 // The interpreter has an assumption that if the memorySize function is 71 // set, then the dynamicGas function is also set. This is a somewhat 72 // arbitrary assumption, and can be removed if we need to -- but it 73 // allows us to avoid a condition check. As long as we have that assumption 74 // in there, this little sanity check prevents us from merging in a 75 // change which violates it. 76 if op.memorySize != nil && op.dynamicGas == nil { 77 panic(fmt.Sprintf("op %v has dynamic memory but not dynamic gas", OpCode(i).String())) 78 } 79 } 80 return jt 81 } 82 83 func newCancunInstructionSet() JumpTable { 84 instructionSet := newShanghaiInstructionSet() 85 enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) 86 enable7516(&instructionSet) // EIP-7516 (BLOBBASEFEE opcode) 87 enable1153(&instructionSet) // EIP-1153 "Transient Storage" 88 enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) 89 enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction 90 return validate(instructionSet) 91 } 92 93 func newShanghaiInstructionSet() JumpTable { 94 instructionSet := newMergeInstructionSet() 95 enable3855(&instructionSet) // PUSH0 instruction 96 enable3860(&instructionSet) // Limit and meter initcode 97 98 return validate(instructionSet) 99 } 100 101 func newMergeInstructionSet() JumpTable { 102 instructionSet := newLondonInstructionSet() 103 instructionSet[PREVRANDAO] = &operation{ 104 execute: opRandom, 105 constantGas: GasQuickStep, 106 minStack: minStack(0, 1), 107 maxStack: maxStack(0, 1), 108 } 109 return validate(instructionSet) 110 } 111 112 // newLondonInstructionSet returns the frontier, homestead, byzantium, 113 // constantinople, istanbul, petersburg, berlin and london instructions. 114 func newLondonInstructionSet() JumpTable { 115 instructionSet := newBerlinInstructionSet() 116 enable3529(&instructionSet) // EIP-3529: Reduction in refunds https://eips.ethereum.org/EIPS/eip-3529 117 enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 118 return validate(instructionSet) 119 } 120 121 // newBerlinInstructionSet returns the frontier, homestead, byzantium, 122 // constantinople, istanbul, petersburg and berlin instructions. 123 func newBerlinInstructionSet() JumpTable { 124 instructionSet := newIstanbulInstructionSet() 125 enable2929(&instructionSet) // Gas cost increases for state access opcodes https://eips.ethereum.org/EIPS/eip-2929 126 return validate(instructionSet) 127 } 128 129 // newIstanbulInstructionSet returns the frontier, homestead, byzantium, 130 // constantinople, istanbul and petersburg instructions. 131 func newIstanbulInstructionSet() JumpTable { 132 instructionSet := newConstantinopleInstructionSet() 133 134 enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344 135 enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 136 enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 137 138 return validate(instructionSet) 139 } 140 141 // newConstantinopleInstructionSet returns the frontier, homestead, 142 // byzantium and constantinople instructions. 143 func newConstantinopleInstructionSet() JumpTable { 144 instructionSet := newByzantiumInstructionSet() 145 instructionSet[SHL] = &operation{ 146 execute: opSHL, 147 constantGas: GasFastestStep, 148 minStack: minStack(2, 1), 149 maxStack: maxStack(2, 1), 150 } 151 instructionSet[SHR] = &operation{ 152 execute: opSHR, 153 constantGas: GasFastestStep, 154 minStack: minStack(2, 1), 155 maxStack: maxStack(2, 1), 156 } 157 instructionSet[SAR] = &operation{ 158 execute: opSAR, 159 constantGas: GasFastestStep, 160 minStack: minStack(2, 1), 161 maxStack: maxStack(2, 1), 162 } 163 instructionSet[EXTCODEHASH] = &operation{ 164 execute: opExtCodeHash, 165 constantGas: params.ExtcodeHashGasConstantinople, 166 minStack: minStack(1, 1), 167 maxStack: maxStack(1, 1), 168 } 169 instructionSet[CREATE2] = &operation{ 170 execute: opCreate2, 171 constantGas: params.Create2Gas, 172 dynamicGas: gasCreate2, 173 minStack: minStack(4, 1), 174 maxStack: maxStack(4, 1), 175 memorySize: memoryCreate2, 176 } 177 return validate(instructionSet) 178 } 179 180 // newByzantiumInstructionSet returns the frontier, homestead and 181 // byzantium instructions. 182 func newByzantiumInstructionSet() JumpTable { 183 instructionSet := newSpuriousDragonInstructionSet() 184 instructionSet[STATICCALL] = &operation{ 185 execute: opStaticCall, 186 constantGas: params.CallGasEIP150, 187 dynamicGas: gasStaticCall, 188 minStack: minStack(6, 1), 189 maxStack: maxStack(6, 1), 190 memorySize: memoryStaticCall, 191 } 192 instructionSet[RETURNDATASIZE] = &operation{ 193 execute: opReturnDataSize, 194 constantGas: GasQuickStep, 195 minStack: minStack(0, 1), 196 maxStack: maxStack(0, 1), 197 } 198 instructionSet[RETURNDATACOPY] = &operation{ 199 execute: opReturnDataCopy, 200 constantGas: GasFastestStep, 201 dynamicGas: gasReturnDataCopy, 202 minStack: minStack(3, 0), 203 maxStack: maxStack(3, 0), 204 memorySize: memoryReturnDataCopy, 205 } 206 instructionSet[REVERT] = &operation{ 207 execute: opRevert, 208 dynamicGas: gasRevert, 209 minStack: minStack(2, 0), 210 maxStack: maxStack(2, 0), 211 memorySize: memoryRevert, 212 } 213 return validate(instructionSet) 214 } 215 216 // EIP 158 a.k.a Spurious Dragon 217 func newSpuriousDragonInstructionSet() JumpTable { 218 instructionSet := newTangerineWhistleInstructionSet() 219 instructionSet[EXP].dynamicGas = gasExpEIP158 220 return validate(instructionSet) 221 } 222 223 // EIP 150 a.k.a Tangerine Whistle 224 func newTangerineWhistleInstructionSet() JumpTable { 225 instructionSet := newHomesteadInstructionSet() 226 instructionSet[BALANCE].constantGas = params.BalanceGasEIP150 227 instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150 228 instructionSet[SLOAD].constantGas = params.SloadGasEIP150 229 instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150 230 instructionSet[CALL].constantGas = params.CallGasEIP150 231 instructionSet[CALLCODE].constantGas = params.CallGasEIP150 232 instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150 233 return validate(instructionSet) 234 } 235 236 // newHomesteadInstructionSet returns the frontier and homestead 237 // instructions that can be executed during the homestead phase. 238 func newHomesteadInstructionSet() JumpTable { 239 instructionSet := newFrontierInstructionSet() 240 instructionSet[DELEGATECALL] = &operation{ 241 execute: opDelegateCall, 242 dynamicGas: gasDelegateCall, 243 constantGas: params.CallGasFrontier, 244 minStack: minStack(6, 1), 245 maxStack: maxStack(6, 1), 246 memorySize: memoryDelegateCall, 247 } 248 return validate(instructionSet) 249 } 250 251 // newFrontierInstructionSet returns the frontier instructions 252 // that can be executed during the frontier phase. 253 func newFrontierInstructionSet() JumpTable { 254 tbl := JumpTable{ 255 STOP: { 256 execute: opStop, 257 constantGas: 0, 258 minStack: minStack(0, 0), 259 maxStack: maxStack(0, 0), 260 }, 261 ADD: { 262 execute: opAdd, 263 constantGas: GasFastestStep, 264 minStack: minStack(2, 1), 265 maxStack: maxStack(2, 1), 266 }, 267 MUL: { 268 execute: opMul, 269 constantGas: GasFastStep, 270 minStack: minStack(2, 1), 271 maxStack: maxStack(2, 1), 272 }, 273 SUB: { 274 execute: opSub, 275 constantGas: GasFastestStep, 276 minStack: minStack(2, 1), 277 maxStack: maxStack(2, 1), 278 }, 279 DIV: { 280 execute: opDiv, 281 constantGas: GasFastStep, 282 minStack: minStack(2, 1), 283 maxStack: maxStack(2, 1), 284 }, 285 SDIV: { 286 execute: opSdiv, 287 constantGas: GasFastStep, 288 minStack: minStack(2, 1), 289 maxStack: maxStack(2, 1), 290 }, 291 MOD: { 292 execute: opMod, 293 constantGas: GasFastStep, 294 minStack: minStack(2, 1), 295 maxStack: maxStack(2, 1), 296 }, 297 SMOD: { 298 execute: opSmod, 299 constantGas: GasFastStep, 300 minStack: minStack(2, 1), 301 maxStack: maxStack(2, 1), 302 }, 303 ADDMOD: { 304 execute: opAddmod, 305 constantGas: GasMidStep, 306 minStack: minStack(3, 1), 307 maxStack: maxStack(3, 1), 308 }, 309 MULMOD: { 310 execute: opMulmod, 311 constantGas: GasMidStep, 312 minStack: minStack(3, 1), 313 maxStack: maxStack(3, 1), 314 }, 315 EXP: { 316 execute: opExp, 317 dynamicGas: gasExpFrontier, 318 minStack: minStack(2, 1), 319 maxStack: maxStack(2, 1), 320 }, 321 SIGNEXTEND: { 322 execute: opSignExtend, 323 constantGas: GasFastStep, 324 minStack: minStack(2, 1), 325 maxStack: maxStack(2, 1), 326 }, 327 LT: { 328 execute: opLt, 329 constantGas: GasFastestStep, 330 minStack: minStack(2, 1), 331 maxStack: maxStack(2, 1), 332 }, 333 GT: { 334 execute: opGt, 335 constantGas: GasFastestStep, 336 minStack: minStack(2, 1), 337 maxStack: maxStack(2, 1), 338 }, 339 SLT: { 340 execute: opSlt, 341 constantGas: GasFastestStep, 342 minStack: minStack(2, 1), 343 maxStack: maxStack(2, 1), 344 }, 345 SGT: { 346 execute: opSgt, 347 constantGas: GasFastestStep, 348 minStack: minStack(2, 1), 349 maxStack: maxStack(2, 1), 350 }, 351 EQ: { 352 execute: opEq, 353 constantGas: GasFastestStep, 354 minStack: minStack(2, 1), 355 maxStack: maxStack(2, 1), 356 }, 357 ISZERO: { 358 execute: opIszero, 359 constantGas: GasFastestStep, 360 minStack: minStack(1, 1), 361 maxStack: maxStack(1, 1), 362 }, 363 AND: { 364 execute: opAnd, 365 constantGas: GasFastestStep, 366 minStack: minStack(2, 1), 367 maxStack: maxStack(2, 1), 368 }, 369 XOR: { 370 execute: opXor, 371 constantGas: GasFastestStep, 372 minStack: minStack(2, 1), 373 maxStack: maxStack(2, 1), 374 }, 375 OR: { 376 execute: opOr, 377 constantGas: GasFastestStep, 378 minStack: minStack(2, 1), 379 maxStack: maxStack(2, 1), 380 }, 381 NOT: { 382 execute: opNot, 383 constantGas: GasFastestStep, 384 minStack: minStack(1, 1), 385 maxStack: maxStack(1, 1), 386 }, 387 BYTE: { 388 execute: opByte, 389 constantGas: GasFastestStep, 390 minStack: minStack(2, 1), 391 maxStack: maxStack(2, 1), 392 }, 393 KECCAK256: { 394 execute: opKeccak256, 395 constantGas: params.Keccak256Gas, 396 dynamicGas: gasKeccak256, 397 minStack: minStack(2, 1), 398 maxStack: maxStack(2, 1), 399 memorySize: memoryKeccak256, 400 }, 401 ADDRESS: { 402 execute: opAddress, 403 constantGas: GasQuickStep, 404 minStack: minStack(0, 1), 405 maxStack: maxStack(0, 1), 406 }, 407 BALANCE: { 408 execute: opBalance, 409 constantGas: params.BalanceGasFrontier, 410 minStack: minStack(1, 1), 411 maxStack: maxStack(1, 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 CALLCODE: { 1035 execute: opCallCode, 1036 constantGas: params.CallGasFrontier, 1037 dynamicGas: gasCallCode, 1038 minStack: minStack(7, 1), 1039 maxStack: maxStack(7, 1), 1040 memorySize: memoryCall, 1041 }, 1042 RETURN: { 1043 execute: opReturn, 1044 dynamicGas: gasReturn, 1045 minStack: minStack(2, 0), 1046 maxStack: maxStack(2, 0), 1047 memorySize: memoryReturn, 1048 }, 1049 SELFDESTRUCT: { 1050 execute: opSelfdestruct, 1051 dynamicGas: gasSelfdestruct, 1052 minStack: minStack(1, 0), 1053 maxStack: maxStack(1, 0), 1054 }, 1055 } 1056 1057 // Fill all unassigned slots with opUndefined. 1058 for i, entry := range tbl { 1059 if entry == nil { 1060 tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0)} 1061 } 1062 } 1063 1064 return validate(tbl) 1065 } 1066 1067 func copyJumpTable(source *JumpTable) *JumpTable { 1068 dest := *source 1069 for i, op := range source { 1070 if op != nil { 1071 opCopy := *op 1072 dest[i] = &opCopy 1073 } 1074 } 1075 return &dest 1076 }