instructions.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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. "math/big"
  20. "github.com/ethereum/go-ethereum/common"
  21. "github.com/ethereum/go-ethereum/common/math"
  22. "github.com/ethereum/go-ethereum/crypto"
  23. "github.com/ethereum/go-ethereum/params"
  24. )
  25. func opAdd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  26. x, y := stack.pop(), stack.pop()
  27. stack.push(U256(x.Add(x, y)))
  28. return nil, nil
  29. }
  30. func opSub(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  31. x, y := stack.pop(), stack.pop()
  32. stack.push(U256(x.Sub(x, y)))
  33. return nil, nil
  34. }
  35. func opMul(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  36. x, y := stack.pop(), stack.pop()
  37. stack.push(U256(x.Mul(x, y)))
  38. return nil, nil
  39. }
  40. func opDiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  41. x, y := stack.pop(), stack.pop()
  42. if y.Cmp(common.Big0) != 0 {
  43. stack.push(U256(x.Div(x, y)))
  44. } else {
  45. stack.push(new(big.Int))
  46. }
  47. return nil, nil
  48. }
  49. func opSdiv(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  50. x, y := S256(stack.pop()), S256(stack.pop())
  51. if y.Cmp(common.Big0) == 0 {
  52. stack.push(new(big.Int))
  53. return nil, nil
  54. } else {
  55. n := new(big.Int)
  56. if new(big.Int).Mul(x, y).Cmp(common.Big0) < 0 {
  57. n.SetInt64(-1)
  58. } else {
  59. n.SetInt64(1)
  60. }
  61. res := x.Div(x.Abs(x), y.Abs(y))
  62. res.Mul(res, n)
  63. stack.push(U256(res))
  64. }
  65. return nil, nil
  66. }
  67. func opMod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  68. x, y := stack.pop(), stack.pop()
  69. if y.Cmp(common.Big0) == 0 {
  70. stack.push(new(big.Int))
  71. } else {
  72. stack.push(U256(x.Mod(x, y)))
  73. }
  74. return nil, nil
  75. }
  76. func opSmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  77. x, y := S256(stack.pop()), S256(stack.pop())
  78. if y.Cmp(common.Big0) == 0 {
  79. stack.push(new(big.Int))
  80. } else {
  81. n := new(big.Int)
  82. if x.Cmp(common.Big0) < 0 {
  83. n.SetInt64(-1)
  84. } else {
  85. n.SetInt64(1)
  86. }
  87. res := x.Mod(x.Abs(x), y.Abs(y))
  88. res.Mul(res, n)
  89. stack.push(U256(res))
  90. }
  91. return nil, nil
  92. }
  93. func opExp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  94. base, exponent := stack.pop(), stack.pop()
  95. stack.push(math.Exp(base, exponent))
  96. return nil, nil
  97. }
  98. func opSignExtend(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  99. back := stack.pop()
  100. if back.Cmp(big.NewInt(31)) < 0 {
  101. bit := uint(back.Uint64()*8 + 7)
  102. num := stack.pop()
  103. mask := back.Lsh(common.Big1, bit)
  104. mask.Sub(mask, common.Big1)
  105. if common.BitTest(num, int(bit)) {
  106. num.Or(num, mask.Not(mask))
  107. } else {
  108. num.And(num, mask)
  109. }
  110. stack.push(U256(num))
  111. }
  112. return nil, nil
  113. }
  114. func opNot(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  115. x := stack.pop()
  116. stack.push(U256(x.Not(x)))
  117. return nil, nil
  118. }
  119. func opLt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  120. x, y := stack.pop(), stack.pop()
  121. if x.Cmp(y) < 0 {
  122. stack.push(big.NewInt(1))
  123. } else {
  124. stack.push(new(big.Int))
  125. }
  126. return nil, nil
  127. }
  128. func opGt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  129. x, y := stack.pop(), stack.pop()
  130. if x.Cmp(y) > 0 {
  131. stack.push(big.NewInt(1))
  132. } else {
  133. stack.push(new(big.Int))
  134. }
  135. return nil, nil
  136. }
  137. func opSlt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  138. x, y := S256(stack.pop()), S256(stack.pop())
  139. if x.Cmp(S256(y)) < 0 {
  140. stack.push(big.NewInt(1))
  141. } else {
  142. stack.push(new(big.Int))
  143. }
  144. return nil, nil
  145. }
  146. func opSgt(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  147. x, y := S256(stack.pop()), S256(stack.pop())
  148. if x.Cmp(y) > 0 {
  149. stack.push(big.NewInt(1))
  150. } else {
  151. stack.push(new(big.Int))
  152. }
  153. return nil, nil
  154. }
  155. func opEq(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  156. x, y := stack.pop(), stack.pop()
  157. if x.Cmp(y) == 0 {
  158. stack.push(big.NewInt(1))
  159. } else {
  160. stack.push(new(big.Int))
  161. }
  162. return nil, nil
  163. }
  164. func opIszero(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  165. x := stack.pop()
  166. if x.Cmp(common.Big0) > 0 {
  167. stack.push(new(big.Int))
  168. } else {
  169. stack.push(big.NewInt(1))
  170. }
  171. return nil, nil
  172. }
  173. func opAnd(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  174. x, y := stack.pop(), stack.pop()
  175. stack.push(x.And(x, y))
  176. return nil, nil
  177. }
  178. func opOr(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  179. x, y := stack.pop(), stack.pop()
  180. stack.push(x.Or(x, y))
  181. return nil, nil
  182. }
  183. func opXor(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  184. x, y := stack.pop(), stack.pop()
  185. stack.push(x.Xor(x, y))
  186. return nil, nil
  187. }
  188. func opByte(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  189. th, val := stack.pop(), stack.pop()
  190. if th.Cmp(big.NewInt(32)) < 0 {
  191. byte := big.NewInt(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
  192. stack.push(byte)
  193. } else {
  194. stack.push(new(big.Int))
  195. }
  196. return nil, nil
  197. }
  198. func opAddmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  199. x, y, z := stack.pop(), stack.pop(), stack.pop()
  200. if z.Cmp(Zero) > 0 {
  201. add := x.Add(x, y)
  202. add.Mod(add, z)
  203. stack.push(U256(add))
  204. } else {
  205. stack.push(new(big.Int))
  206. }
  207. return nil, nil
  208. }
  209. func opMulmod(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  210. x, y, z := stack.pop(), stack.pop(), stack.pop()
  211. if z.Cmp(Zero) > 0 {
  212. mul := x.Mul(x, y)
  213. mul.Mod(mul, z)
  214. stack.push(U256(mul))
  215. } else {
  216. stack.push(new(big.Int))
  217. }
  218. return nil, nil
  219. }
  220. func opSha3(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  221. offset, size := stack.pop(), stack.pop()
  222. hash := crypto.Keccak256(memory.Get(offset.Int64(), size.Int64()))
  223. stack.push(common.BytesToBig(hash))
  224. return nil, nil
  225. }
  226. func opAddress(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  227. stack.push(common.Bytes2Big(contract.Address().Bytes()))
  228. return nil, nil
  229. }
  230. func opBalance(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  231. addr := common.BigToAddress(stack.pop())
  232. balance := env.StateDB.GetBalance(addr)
  233. stack.push(new(big.Int).Set(balance))
  234. return nil, nil
  235. }
  236. func opOrigin(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  237. stack.push(env.Origin.Big())
  238. return nil, nil
  239. }
  240. func opCaller(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  241. stack.push(contract.Caller().Big())
  242. return nil, nil
  243. }
  244. func opCallValue(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  245. stack.push(new(big.Int).Set(contract.value))
  246. return nil, nil
  247. }
  248. func opCalldataLoad(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  249. stack.push(common.Bytes2Big(getData(contract.Input, stack.pop(), common.Big32)))
  250. return nil, nil
  251. }
  252. func opCalldataSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  253. stack.push(big.NewInt(int64(len(contract.Input))))
  254. return nil, nil
  255. }
  256. func opCalldataCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  257. var (
  258. mOff = stack.pop()
  259. cOff = stack.pop()
  260. l = stack.pop()
  261. )
  262. memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
  263. return nil, nil
  264. }
  265. func opExtCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  266. addr := common.BigToAddress(stack.pop())
  267. l := big.NewInt(int64(env.StateDB.GetCodeSize(addr)))
  268. stack.push(l)
  269. return nil, nil
  270. }
  271. func opCodeSize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  272. l := big.NewInt(int64(len(contract.Code)))
  273. stack.push(l)
  274. return nil, nil
  275. }
  276. func opCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  277. var (
  278. mOff = stack.pop()
  279. cOff = stack.pop()
  280. l = stack.pop()
  281. )
  282. codeCopy := getData(contract.Code, cOff, l)
  283. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  284. return nil, nil
  285. }
  286. func opExtCodeCopy(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  287. var (
  288. addr = common.BigToAddress(stack.pop())
  289. mOff = stack.pop()
  290. cOff = stack.pop()
  291. l = stack.pop()
  292. )
  293. codeCopy := getData(env.StateDB.GetCode(addr), cOff, l)
  294. memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
  295. return nil, nil
  296. }
  297. func opGasprice(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  298. stack.push(new(big.Int).Set(env.GasPrice))
  299. return nil, nil
  300. }
  301. func opBlockhash(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  302. num := stack.pop()
  303. n := new(big.Int).Sub(env.BlockNumber, common.Big257)
  304. if num.Cmp(n) > 0 && num.Cmp(env.BlockNumber) < 0 {
  305. stack.push(env.GetHash(num.Uint64()).Big())
  306. } else {
  307. stack.push(new(big.Int))
  308. }
  309. return nil, nil
  310. }
  311. func opCoinbase(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  312. stack.push(env.Coinbase.Big())
  313. return nil, nil
  314. }
  315. func opTimestamp(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  316. stack.push(U256(new(big.Int).Set(env.Time)))
  317. return nil, nil
  318. }
  319. func opNumber(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  320. stack.push(U256(new(big.Int).Set(env.BlockNumber)))
  321. return nil, nil
  322. }
  323. func opDifficulty(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  324. stack.push(U256(new(big.Int).Set(env.Difficulty)))
  325. return nil, nil
  326. }
  327. func opGasLimit(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  328. stack.push(U256(new(big.Int).Set(env.GasLimit)))
  329. return nil, nil
  330. }
  331. func opPop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  332. stack.pop()
  333. return nil, nil
  334. }
  335. func opMload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  336. offset := stack.pop()
  337. val := common.BigD(memory.Get(offset.Int64(), 32))
  338. stack.push(val)
  339. return nil, nil
  340. }
  341. func opMstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  342. // pop value of the stack
  343. mStart, val := stack.pop(), stack.pop()
  344. memory.Set(mStart.Uint64(), 32, common.BigToBytes(val, 256))
  345. return nil, nil
  346. }
  347. func opMstore8(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  348. off, val := stack.pop().Int64(), stack.pop().Int64()
  349. memory.store[off] = byte(val & 0xff)
  350. return nil, nil
  351. }
  352. func opSload(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  353. loc := common.BigToHash(stack.pop())
  354. val := env.StateDB.GetState(contract.Address(), loc).Big()
  355. stack.push(val)
  356. return nil, nil
  357. }
  358. func opSstore(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  359. loc := common.BigToHash(stack.pop())
  360. val := stack.pop()
  361. env.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))
  362. return nil, nil
  363. }
  364. func opJump(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  365. pos := stack.pop()
  366. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  367. nop := contract.GetOp(pos.Uint64())
  368. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  369. }
  370. *pc = pos.Uint64()
  371. return nil, nil
  372. }
  373. func opJumpi(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  374. pos, cond := stack.pop(), stack.pop()
  375. if cond.Cmp(common.BigTrue) >= 0 {
  376. if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
  377. nop := contract.GetOp(pos.Uint64())
  378. return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
  379. }
  380. *pc = pos.Uint64()
  381. } else {
  382. *pc++
  383. }
  384. return nil, nil
  385. }
  386. func opJumpdest(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  387. return nil, nil
  388. }
  389. func opPc(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  390. stack.push(new(big.Int).SetUint64(*pc))
  391. return nil, nil
  392. }
  393. func opMsize(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  394. stack.push(big.NewInt(int64(memory.Len())))
  395. return nil, nil
  396. }
  397. func opGas(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  398. stack.push(new(big.Int).Set(contract.Gas))
  399. return nil, nil
  400. }
  401. func opCreate(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  402. var (
  403. value = stack.pop()
  404. offset, size = stack.pop(), stack.pop()
  405. input = memory.Get(offset.Int64(), size.Int64())
  406. gas = new(big.Int).Set(contract.Gas)
  407. )
  408. if env.ChainConfig().IsEIP150(env.BlockNumber) {
  409. gas.Div(gas, n64)
  410. gas = gas.Sub(contract.Gas, gas)
  411. }
  412. contract.UseGas(gas)
  413. _, addr, suberr := env.Create(contract, input, gas, value)
  414. // Push item on the stack based on the returned error. If the ruleset is
  415. // homestead we must check for CodeStoreOutOfGasError (homestead only
  416. // rule) and treat as an error, if the ruleset is frontier we must
  417. // ignore this error and pretend the operation was successful.
  418. if env.ChainConfig().IsHomestead(env.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
  419. stack.push(new(big.Int))
  420. } else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
  421. stack.push(new(big.Int))
  422. } else {
  423. stack.push(addr.Big())
  424. }
  425. return nil, nil
  426. }
  427. func opCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  428. gas := stack.pop()
  429. // pop gas and value of the stack.
  430. addr, value := stack.pop(), stack.pop()
  431. value = U256(value)
  432. // pop input size and offset
  433. inOffset, inSize := stack.pop(), stack.pop()
  434. // pop return size and offset
  435. retOffset, retSize := stack.pop(), stack.pop()
  436. address := common.BigToAddress(addr)
  437. // Get the arguments from the memory
  438. args := memory.Get(inOffset.Int64(), inSize.Int64())
  439. if len(value.Bytes()) > 0 {
  440. gas.Add(gas, params.CallStipend)
  441. }
  442. ret, err := env.Call(contract, address, args, gas, value)
  443. if err != nil {
  444. stack.push(new(big.Int))
  445. } else {
  446. stack.push(big.NewInt(1))
  447. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  448. }
  449. return nil, nil
  450. }
  451. func opCallCode(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  452. gas := stack.pop()
  453. // pop gas and value of the stack.
  454. addr, value := stack.pop(), stack.pop()
  455. value = U256(value)
  456. // pop input size and offset
  457. inOffset, inSize := stack.pop(), stack.pop()
  458. // pop return size and offset
  459. retOffset, retSize := stack.pop(), stack.pop()
  460. address := common.BigToAddress(addr)
  461. // Get the arguments from the memory
  462. args := memory.Get(inOffset.Int64(), inSize.Int64())
  463. if len(value.Bytes()) > 0 {
  464. gas.Add(gas, params.CallStipend)
  465. }
  466. ret, err := env.CallCode(contract, address, args, gas, value)
  467. if err != nil {
  468. stack.push(new(big.Int))
  469. } else {
  470. stack.push(big.NewInt(1))
  471. memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
  472. }
  473. return nil, nil
  474. }
  475. func opDelegateCall(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  476. // if not homestead return an error. DELEGATECALL is not supported
  477. // during pre-homestead.
  478. if !env.ChainConfig().IsHomestead(env.BlockNumber) {
  479. return nil, fmt.Errorf("invalid opcode %x", DELEGATECALL)
  480. }
  481. gas, to, inOffset, inSize, outOffset, outSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
  482. toAddr := common.BigToAddress(to)
  483. args := memory.Get(inOffset.Int64(), inSize.Int64())
  484. ret, err := env.DelegateCall(contract, toAddr, args, gas)
  485. if err != nil {
  486. stack.push(new(big.Int))
  487. } else {
  488. stack.push(big.NewInt(1))
  489. memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
  490. }
  491. return nil, nil
  492. }
  493. func opReturn(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  494. offset, size := stack.pop(), stack.pop()
  495. ret := memory.GetPtr(offset.Int64(), size.Int64())
  496. return ret, nil
  497. }
  498. func opStop(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  499. return nil, nil
  500. }
  501. func opSuicide(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  502. balance := env.StateDB.GetBalance(contract.Address())
  503. env.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
  504. env.StateDB.Suicide(contract.Address())
  505. return nil, nil
  506. }
  507. // following functions are used by the instruction jump table
  508. // make log instruction function
  509. func makeLog(size int) executionFunc {
  510. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  511. topics := make([]common.Hash, size)
  512. mStart, mSize := stack.pop(), stack.pop()
  513. for i := 0; i < size; i++ {
  514. topics[i] = common.BigToHash(stack.pop())
  515. }
  516. d := memory.Get(mStart.Int64(), mSize.Int64())
  517. log := NewLog(contract.Address(), topics, d, env.BlockNumber.Uint64())
  518. env.StateDB.AddLog(log)
  519. return nil, nil
  520. }
  521. }
  522. // make push instruction function
  523. func makePush(size uint64, bsize *big.Int) executionFunc {
  524. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  525. byts := getData(contract.Code, new(big.Int).SetUint64(*pc+1), bsize)
  526. stack.push(common.Bytes2Big(byts))
  527. *pc += size
  528. return nil, nil
  529. }
  530. }
  531. // make push instruction function
  532. func makeDup(size int64) executionFunc {
  533. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  534. stack.dup(int(size))
  535. return nil, nil
  536. }
  537. }
  538. // make swap instruction function
  539. func makeSwap(size int64) executionFunc {
  540. // switch n + 1 otherwise n would be swapped with n
  541. size += 1
  542. return func(pc *uint64, env *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
  543. stack.swap(int(size))
  544. return nil, nil
  545. }
  546. }