instructions.go 21.1 KB
Newer Older
1
// Copyright 2015 The go-ethereum Authors
2 3 4 5 6 7 8 9 10 11 12 13 14 15
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16

17 18 19
package vm

import (
20
	"fmt"
21 22 23
	"math/big"

	"github.com/ethereum/go-ethereum/common"
24
	"github.com/ethereum/go-ethereum/common/math"
25
	"github.com/ethereum/go-ethereum/core/types"
26 27 28 29
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/params"
)

30 31 32
var (
	bigZero = new(big.Int)
)
33 34

func opAdd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
35
	x, y := stack.pop(), stack.pop()
36
	stack.push(math.U256(x.Add(x, y)))
37 38 39

	evm.interpreter.intPool.put(y)

40
	return nil, nil
41 42
}

43
func opSub(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
44
	x, y := stack.pop(), stack.pop()
45
	stack.push(math.U256(x.Sub(x, y)))
46 47 48

	evm.interpreter.intPool.put(y)

49
	return nil, nil
50 51
}

52
func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
53
	x, y := stack.pop(), stack.pop()
54
	stack.push(math.U256(x.Mul(x, y)))
55 56 57

	evm.interpreter.intPool.put(y)

58
	return nil, nil
59 60
}

61
func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
62
	x, y := stack.pop(), stack.pop()
63
	if y.Sign() != 0 {
64
		stack.push(math.U256(x.Div(x, y)))
65 66
	} else {
		stack.push(new(big.Int))
67
	}
68 69 70

	evm.interpreter.intPool.put(y)

71
	return nil, nil
72 73
}

74
func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
75
	x, y := math.S256(stack.pop()), math.S256(stack.pop())
76
	if y.Sign() == 0 {
77
		stack.push(new(big.Int))
78
		return nil, nil
79 80
	} else {
		n := new(big.Int)
81
		if evm.interpreter.intPool.get().Mul(x, y).Sign() < 0 {
82 83 84 85 86
			n.SetInt64(-1)
		} else {
			n.SetInt64(1)
		}

87 88
		res := x.Div(x.Abs(x), y.Abs(y))
		res.Mul(res, n)
89

90
		stack.push(math.U256(res))
91
	}
92
	evm.interpreter.intPool.put(y)
93
	return nil, nil
94 95
}

96
func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
97
	x, y := stack.pop(), stack.pop()
98
	if y.Sign() == 0 {
99
		stack.push(new(big.Int))
100
	} else {
101
		stack.push(math.U256(x.Mod(x, y)))
102
	}
103
	evm.interpreter.intPool.put(y)
104
	return nil, nil
105 106
}

107
func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
108
	x, y := math.S256(stack.pop()), math.S256(stack.pop())
109

110
	if y.Sign() == 0 {
111
		stack.push(new(big.Int))
112 113
	} else {
		n := new(big.Int)
114
		if x.Sign() < 0 {
115 116 117 118 119
			n.SetInt64(-1)
		} else {
			n.SetInt64(1)
		}

120 121
		res := x.Mod(x.Abs(x), y.Abs(y))
		res.Mul(res, n)
122

123
		stack.push(math.U256(res))
124
	}
125
	evm.interpreter.intPool.put(y)
126
	return nil, nil
127 128
}

129
func opExp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
130 131
	base, exponent := stack.pop(), stack.pop()
	stack.push(math.Exp(base, exponent))
132 133 134

	evm.interpreter.intPool.put(base, exponent)

135
	return nil, nil
136 137
}

138
func opSignExtend(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
139 140 141 142
	back := stack.pop()
	if back.Cmp(big.NewInt(31)) < 0 {
		bit := uint(back.Uint64()*8 + 7)
		num := stack.pop()
143
		mask := back.Lsh(common.Big1, bit)
144
		mask.Sub(mask, common.Big1)
145
		if num.Bit(int(bit)) > 0 {
146 147 148 149 150
			num.Or(num, mask.Not(mask))
		} else {
			num.And(num, mask)
		}

151
		stack.push(math.U256(num))
152
	}
153 154

	evm.interpreter.intPool.put(back)
155
	return nil, nil
156 157
}

158
func opNot(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
159
	x := stack.pop()
160
	stack.push(math.U256(x.Not(x)))
161
	return nil, nil
162 163
}

164
func opLt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
165 166
	x, y := stack.pop(), stack.pop()
	if x.Cmp(y) < 0 {
167
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
168
	} else {
169
		stack.push(new(big.Int))
170
	}
171 172

	evm.interpreter.intPool.put(x, y)
173
	return nil, nil
174 175
}

176
func opGt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
177 178
	x, y := stack.pop(), stack.pop()
	if x.Cmp(y) > 0 {
179
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
180
	} else {
181
		stack.push(new(big.Int))
182
	}
183 184

	evm.interpreter.intPool.put(x, y)
185
	return nil, nil
186 187
}

188
func opSlt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
189 190
	x, y := math.S256(stack.pop()), math.S256(stack.pop())
	if x.Cmp(math.S256(y)) < 0 {
191
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
192
	} else {
193
		stack.push(new(big.Int))
194
	}
195 196

	evm.interpreter.intPool.put(x, y)
197
	return nil, nil
198 199
}

200
func opSgt(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
201
	x, y := math.S256(stack.pop()), math.S256(stack.pop())
202
	if x.Cmp(y) > 0 {
203
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
204
	} else {
205
		stack.push(new(big.Int))
206
	}
207 208

	evm.interpreter.intPool.put(x, y)
209
	return nil, nil
210 211
}

212
func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
213 214
	x, y := stack.pop(), stack.pop()
	if x.Cmp(y) == 0 {
215
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
216
	} else {
217
		stack.push(new(big.Int))
218
	}
219 220

	evm.interpreter.intPool.put(x, y)
221
	return nil, nil
222 223
}

224
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
225
	x := stack.pop()
226
	if x.Sign() > 0 {
227
		stack.push(new(big.Int))
228
	} else {
229
		stack.push(evm.interpreter.intPool.get().SetUint64(1))
230
	}
231 232

	evm.interpreter.intPool.put(x)
233
	return nil, nil
234 235
}

236
func opAnd(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
237
	x, y := stack.pop(), stack.pop()
238
	stack.push(x.And(x, y))
239 240

	evm.interpreter.intPool.put(y)
241
	return nil, nil
242
}
243
func opOr(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
244
	x, y := stack.pop(), stack.pop()
245
	stack.push(x.Or(x, y))
246 247

	evm.interpreter.intPool.put(y)
248
	return nil, nil
249
}
250
func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
251
	x, y := stack.pop(), stack.pop()
252
	stack.push(x.Xor(x, y))
253 254

	evm.interpreter.intPool.put(y)
255
	return nil, nil
256
}
257

258
func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
259 260
	th, val := stack.pop(), stack.peek()
	if th.Cmp(common.Big32) < 0 {
261 262
		b := math.Byte(val, 32, int(th.Int64()))
		val.SetUint64(uint64(b))
263
	} else {
264
		val.SetUint64(0)
265
	}
266
	evm.interpreter.intPool.put(th)
267
	return nil, nil
268
}
269
func opAddmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
270
	x, y, z := stack.pop(), stack.pop(), stack.pop()
271
	if z.Cmp(bigZero) > 0 {
272 273
		add := x.Add(x, y)
		add.Mod(add, z)
274
		stack.push(math.U256(add))
275 276
	} else {
		stack.push(new(big.Int))
277
	}
278 279

	evm.interpreter.intPool.put(y, z)
280
	return nil, nil
281
}
282
func opMulmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
283
	x, y, z := stack.pop(), stack.pop(), stack.pop()
284
	if z.Cmp(bigZero) > 0 {
285 286
		mul := x.Mul(x, y)
		mul.Mod(mul, z)
287
		stack.push(math.U256(mul))
288 289
	} else {
		stack.push(new(big.Int))
290
	}
291 292

	evm.interpreter.intPool.put(y, z)
293
	return nil, nil
294 295
}

296
func opSha3(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
297
	offset, size := stack.pop(), stack.pop()
298 299 300
	data := memory.Get(offset.Int64(), size.Int64())
	hash := crypto.Keccak256(data)

301 302
	if evm.vmConfig.EnablePreimageRecording {
		evm.StateDB.AddPreimage(common.BytesToHash(hash), data)
303
	}
304

305
	stack.push(new(big.Int).SetBytes(hash))
306 307

	evm.interpreter.intPool.put(offset, size)
308
	return nil, nil
309 310
}

311
func opAddress(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
312
	stack.push(contract.Address().Big())
313
	return nil, nil
314 315
}

316
func opBalance(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
317
	addr := common.BigToAddress(stack.pop())
318
	balance := evm.StateDB.GetBalance(addr)
319 320

	stack.push(new(big.Int).Set(balance))
321
	return nil, nil
322 323
}

324 325
func opOrigin(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.Origin.Big())
326
	return nil, nil
327 328
}

329
func opCaller(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
330
	stack.push(contract.Caller().Big())
331
	return nil, nil
332 333
}

334 335
func opCallValue(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().Set(contract.value))
336
	return nil, nil
337 338
}

339
func opCalldataLoad(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
340
	stack.push(new(big.Int).SetBytes(getData(contract.Input, stack.pop(), common.Big32)))
341
	return nil, nil
342 343
}

344 345
func opCalldataSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().SetInt64(int64(len(contract.Input))))
346
	return nil, nil
347 348
}

349
func opCalldataCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
350 351 352 353 354
	var (
		mOff = stack.pop()
		cOff = stack.pop()
		l    = stack.pop()
	)
355
	memory.Set(mOff.Uint64(), l.Uint64(), getData(contract.Input, cOff, l))
356 357

	evm.interpreter.intPool.put(mOff, cOff, l)
358
	return nil, nil
359 360
}

361 362 363 364 365 366 367
func opExtCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	a := stack.pop()

	addr := common.BigToAddress(a)
	a.SetInt64(int64(evm.StateDB.GetCodeSize(addr)))
	stack.push(a)

368
	return nil, nil
369 370
}

371 372
func opCodeSize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	l := evm.interpreter.intPool.get().SetInt64(int64(len(contract.Code)))
373
	stack.push(l)
374
	return nil, nil
375 376
}

377
func opCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
378 379 380 381 382
	var (
		mOff = stack.pop()
		cOff = stack.pop()
		l    = stack.pop()
	)
383
	codeCopy := getData(contract.Code, cOff, l)
384 385

	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
386 387

	evm.interpreter.intPool.put(mOff, cOff, l)
388
	return nil, nil
389 390
}

391
func opExtCodeCopy(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
392 393 394 395 396 397
	var (
		addr = common.BigToAddress(stack.pop())
		mOff = stack.pop()
		cOff = stack.pop()
		l    = stack.pop()
	)
398
	codeCopy := getData(evm.StateDB.GetCode(addr), cOff, l)
399 400

	memory.Set(mOff.Uint64(), l.Uint64(), codeCopy)
401 402 403

	evm.interpreter.intPool.put(mOff, cOff, l)

404
	return nil, nil
405 406
}

407 408
func opGasprice(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().Set(evm.GasPrice))
409
	return nil, nil
410 411
}

412
func opBlockhash(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
413 414
	num := stack.pop()

415 416 417
	n := evm.interpreter.intPool.get().Sub(evm.BlockNumber, common.Big257)
	if num.Cmp(n) > 0 && num.Cmp(evm.BlockNumber) < 0 {
		stack.push(evm.GetHash(num.Uint64()).Big())
418
	} else {
419
		stack.push(new(big.Int))
420
	}
421 422

	evm.interpreter.intPool.put(num, n)
423
	return nil, nil
424 425
}

426 427
func opCoinbase(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.Coinbase.Big())
428
	return nil, nil
429 430
}

431
func opTimestamp(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
432
	stack.push(math.U256(new(big.Int).Set(evm.Time)))
433
	return nil, nil
434 435
}

436
func opNumber(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
437
	stack.push(math.U256(new(big.Int).Set(evm.BlockNumber)))
438
	return nil, nil
439 440
}

441
func opDifficulty(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
442
	stack.push(math.U256(new(big.Int).Set(evm.Difficulty)))
443
	return nil, nil
444 445
}

446
func opGasLimit(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
447
	stack.push(math.U256(new(big.Int).Set(evm.GasLimit)))
448
	return nil, nil
449 450
}

451 452
func opPop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	evm.interpreter.intPool.put(stack.pop())
453
	return nil, nil
454 455
}

456
func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
457
	offset := stack.pop()
458
	val := new(big.Int).SetBytes(memory.Get(offset.Int64(), 32))
459
	stack.push(val)
460 461

	evm.interpreter.intPool.put(offset)
462
	return nil, nil
463 464
}

465
func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
466 467
	// pop value of the stack
	mStart, val := stack.pop(), stack.pop()
468
	memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32))
469 470

	evm.interpreter.intPool.put(mStart, val)
471
	return nil, nil
472 473
}

474
func opMstore8(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
475 476
	off, val := stack.pop().Int64(), stack.pop().Int64()
	memory.store[off] = byte(val & 0xff)
477

478
	return nil, nil
479 480
}

481
func opSload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
482
	loc := common.BigToHash(stack.pop())
483
	val := evm.StateDB.GetState(contract.Address(), loc).Big()
484
	stack.push(val)
485
	return nil, nil
486 487
}

488
func opSstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
489 490
	loc := common.BigToHash(stack.pop())
	val := stack.pop()
491 492 493
	evm.StateDB.SetState(contract.Address(), loc, common.BigToHash(val))

	evm.interpreter.intPool.put(val)
494
	return nil, nil
495 496
}

497
func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
498 499 500 501 502 503
	pos := stack.pop()
	if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
		nop := contract.GetOp(pos.Uint64())
		return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
	}
	*pc = pos.Uint64()
504 505

	evm.interpreter.intPool.put(pos)
506
	return nil, nil
507
}
508
func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
509
	pos, cond := stack.pop(), stack.pop()
510
	if cond.Sign() != 0 {
511 512 513 514 515 516 517 518
		if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
			nop := contract.GetOp(pos.Uint64())
			return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
		}
		*pc = pos.Uint64()
	} else {
		*pc++
	}
519 520

	evm.interpreter.intPool.put(pos, cond)
521
	return nil, nil
522
}
523
func opJumpdest(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
524
	return nil, nil
525
}
526

527 528
func opPc(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().SetUint64(*pc))
529
	return nil, nil
530 531
}

532 533
func opMsize(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().SetInt64(int64(memory.Len())))
534
	return nil, nil
535 536
}

537 538
func opGas(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	stack.push(evm.interpreter.intPool.get().SetUint64(contract.Gas))
539
	return nil, nil
540 541
}

542
func opCreate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
543 544 545 546
	var (
		value        = stack.pop()
		offset, size = stack.pop(), stack.pop()
		input        = memory.Get(offset.Int64(), size.Int64())
547
		gas          = contract.Gas
548
	)
549 550
	if evm.ChainConfig().IsEIP150(evm.BlockNumber) {
		gas -= gas / 64
551 552 553
	}

	contract.UseGas(gas)
554
	_, addr, returnGas, suberr := evm.Create(contract, input, gas, value)
555 556 557 558
	// Push item on the stack based on the returned error. If the ruleset is
	// homestead we must check for CodeStoreOutOfGasError (homestead only
	// rule) and treat as an error, if the ruleset is frontier we must
	// ignore this error and pretend the operation was successful.
559
	if evm.ChainConfig().IsHomestead(evm.BlockNumber) && suberr == ErrCodeStoreOutOfGas {
560
		stack.push(new(big.Int))
561
	} else if suberr != nil && suberr != ErrCodeStoreOutOfGas {
562 563 564 565
		stack.push(new(big.Int))
	} else {
		stack.push(addr.Big())
	}
566 567 568 569
	contract.Gas += returnGas

	evm.interpreter.intPool.put(value, offset, size)

570
	return nil, nil
571 572
}

573 574
func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	gas := stack.pop().Uint64()
575 576
	// pop gas and value of the stack.
	addr, value := stack.pop(), stack.pop()
577
	value = math.U256(value)
578 579 580 581 582 583 584 585 586 587
	// pop input size and offset
	inOffset, inSize := stack.pop(), stack.pop()
	// pop return size and offset
	retOffset, retSize := stack.pop(), stack.pop()

	address := common.BigToAddress(addr)

	// Get the arguments from the memory
	args := memory.Get(inOffset.Int64(), inSize.Int64())

588
	if value.Sign() != 0 {
589
		gas += params.CallStipend
590 591
	}

592
	ret, returnGas, err := evm.Call(contract, address, args, gas, value)
593
	if err != nil {
594
		stack.push(new(big.Int))
595
	} else {
596
		stack.push(big.NewInt(1))
597 598 599

		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
	}
600 601 602
	contract.Gas += returnGas

	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
603
	return ret, nil
604 605
}

606 607
func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	gas := stack.pop().Uint64()
608 609
	// pop gas and value of the stack.
	addr, value := stack.pop(), stack.pop()
610
	value = math.U256(value)
611 612 613 614 615 616 617 618 619 620
	// pop input size and offset
	inOffset, inSize := stack.pop(), stack.pop()
	// pop return size and offset
	retOffset, retSize := stack.pop(), stack.pop()

	address := common.BigToAddress(addr)

	// Get the arguments from the memory
	args := memory.Get(inOffset.Int64(), inSize.Int64())

621
	if value.Sign() != 0 {
622
		gas += params.CallStipend
623 624
	}

625
	ret, returnGas, err := evm.CallCode(contract, address, args, gas, value)
626
	if err != nil {
627
		stack.push(new(big.Int))
628 629

	} else {
630
		stack.push(big.NewInt(1))
631 632 633

		memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
	}
634 635 636
	contract.Gas += returnGas

	evm.interpreter.intPool.put(addr, value, inOffset, inSize, retOffset, retSize)
637
	return ret, nil
638 639
}

640 641
func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	gas, to, inOffset, inSize, outOffset, outSize := stack.pop().Uint64(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
642 643 644

	toAddr := common.BigToAddress(to)
	args := memory.Get(inOffset.Int64(), inSize.Int64())
645 646

	ret, returnGas, err := evm.DelegateCall(contract, toAddr, args, gas)
647 648 649 650 651 652
	if err != nil {
		stack.push(new(big.Int))
	} else {
		stack.push(big.NewInt(1))
		memory.Set(outOffset.Uint64(), outSize.Uint64(), ret)
	}
653 654 655
	contract.Gas += returnGas

	evm.interpreter.intPool.put(to, inOffset, inSize, outOffset, outSize)
656
	return ret, nil
657 658
}

659
func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
660 661 662
	offset, size := stack.pop(), stack.pop()
	ret := memory.GetPtr(offset.Int64(), size.Int64())

663
	evm.interpreter.intPool.put(offset, size)
664

665
	return ret, nil
666
}
667

668
func opStop(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
669
	return nil, nil
670 671
}

672 673 674
func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
	balance := evm.StateDB.GetBalance(contract.Address())
	evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance)
675

676
	evm.StateDB.Suicide(contract.Address())
677 678

	return nil, nil
679 680 681 682 683
}

// following functions are used by the instruction jump  table

// make log instruction function
684
func makeLog(size int) executionFunc {
685
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
686 687 688 689 690 691 692
		topics := make([]common.Hash, size)
		mStart, mSize := stack.pop(), stack.pop()
		for i := 0; i < size; i++ {
			topics[i] = common.BigToHash(stack.pop())
		}

		d := memory.Get(mStart.Int64(), mSize.Int64())
693
		evm.StateDB.AddLog(&types.Log{
694 695 696 697 698
			Address: contract.Address(),
			Topics:  topics,
			Data:    d,
			// This is a non-consensus field, but assigned here because
			// core/state doesn't know the current block number.
699
			BlockNumber: evm.BlockNumber.Uint64(),
700
		})
701 702

		evm.interpreter.intPool.put(mStart, mSize)
703
		return nil, nil
704 705
	}
}
706

707
// make push instruction function
708
func makePush(size uint64, pushByteSize int) executionFunc {
709
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
		codeLen := len(contract.Code)

		startMin := codeLen
		if int(*pc+1) < startMin {
			startMin = int(*pc + 1)
		}

		endMin := codeLen
		if startMin+pushByteSize < endMin {
			endMin = startMin + pushByteSize
		}

		integer := evm.interpreter.intPool.get()
		stack.push(integer.SetBytes(common.RightPadBytes(contract.Code[startMin:endMin], pushByteSize)))

725
		*pc += size
726
		return nil, nil
727 728
	}
}
729

730
// make push instruction function
731
func makeDup(size int64) executionFunc {
732
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
733
		stack.dup(evm.interpreter.intPool, int(size))
734
		return nil, nil
735 736
	}
}
737

738
// make swap instruction function
739
func makeSwap(size int64) executionFunc {
740 741
	// switch n + 1 otherwise n would be swapped with n
	size += 1
742
	return func(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
743
		stack.swap(int(size))
744
		return nil, nil
745
	}
746
}