Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- pc = uint64(0) // program counter
- for ; ; instrCount++ {
- // Get the memory location of pc
- op = contract.GetOp(pc)
- // calculate the new memory size and gas price for the current executing opcode
- newMemSize, cost, err = calculateGasAndSize(evm.env, contract, caller, op, statedb, mem, stack)
- if err != nil {
- return nil, err
- }
- // Use the calculated gas. When insufficient gas is present, use all gas and return an
- // Out Of Gas error
- if !contract.UseGas(cost) {
- return nil, OutOfGasError
- }
- // Resize the memory calculated previously
- mem.Resize(newMemSize.Uint64())
- // Add a log message
- if evm.cfg.Debug {
- evm.logger.captureState(pc, op, contract.Gas, cost, mem, stack, contract, evm.env.Depth(), nil)
- }
- if opPtr := evm.jumpTable[op]; opPtr.valid {
- if opPtr.fn != nil {
- opPtr.fn(instruction{}, &pc, evm.env, contract, mem, stack)
- } else {
- switch op {
- case PC:
- opPc(instruction{data: new(big.Int).SetUint64(pc)}, &pc, evm.env, contract, mem, stack)
- case JUMP:
- if err := jump(pc, stack.pop()); err != nil {
- return nil, err
- }
- continue
- case JUMPI:
- pos, cond := stack.pop(), stack.pop()
- if cond.Cmp(common.BigTrue) >= 0 {
- if err := jump(pc, pos); err != nil {
- return nil, err
- }
- continue
- }
- case RETURN:
- offset, size := stack.pop(), stack.pop()
- ret := mem.GetPtr(offset.Int64(), size.Int64())
- return ret, nil
- case SUICIDE:
- opSuicide(instruction{}, nil, evm.env, contract, mem, stack)
- fallthrough
- case STOP: // Stop the contract
- return nil, nil
- }
- }
- } else {
- return nil, fmt.Errorf("Invalid opcode %x", op)
- }
- pc++
- }
Add Comment
Please, Sign In to add comment