jump_table.go 27 KB

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