Class: Ciri::EVM::MachineState

Inherits:
Object
  • Object
show all
Includes:
Utils::Logger
Defined in:
lib/ciri/evm/machine_state.rb

Overview

represent current vm status, include stack, memory..

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(memory: ''.b, stack: []) ⇒ MachineState

Returns a new instance of MachineState.



31
32
33
34
# File 'lib/ciri/evm/machine_state.rb', line 31

def initialize(memory: ''.b, stack: [])
  @memory = memory
  @stack = stack
end

Instance Attribute Details

#memoryObject (readonly)

Returns the value of attribute memory.



29
30
31
# File 'lib/ciri/evm/machine_state.rb', line 29

def memory
  @memory
end

#stackObject (readonly)

Returns the value of attribute stack.



29
30
31
# File 'lib/ciri/evm/machine_state.rb', line 29

def stack
  @stack
end

Instance Method Details

#extend_memory(context, pos, size) ⇒ Object

extend vm memory, used for memory_gas calculation



80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ciri/evm/machine_state.rb', line 80

def extend_memory(context, pos, size)
  if size != 0 && (new_item = Utils.ceil_div(pos + size, 32)) > memory_item
    debug("extend memory: from #{memory_item} -> #{new_item}")
    old_cost_gas = context.fork_schema.gas_of_memory memory_item
    new_cost_gas = context.fork_schema.gas_of_memory new_item
    context.consume_gas(new_cost_gas - old_cost_gas)

    extend_size = (new_item - memory_item) * 32
    self.memory << "\x00".b * extend_size
  end
end

#get_stack(index, type = nil) ⇒ Object

get item from stack



48
49
50
51
# File 'lib/ciri/evm/machine_state.rb', line 48

def get_stack(index, type = nil)
  item = stack[index]
  item && Serialize.deserialize(type, item)
end

#memory_fetch(start, size) ⇒ Object

fetch data from memory



66
67
68
69
70
71
72
73
# File 'lib/ciri/evm/machine_state.rb', line 66

def memory_fetch(start, size)
  if size > 0 && start < memory.size && start + size - 1 < memory.size
    memory[start..(start + size - 1)]
  else
    # prevent size is too large
    "\x00".b * [size, memory.size].min
  end
end

#memory_itemObject



75
76
77
# File 'lib/ciri/evm/machine_state.rb', line 75

def memory_item
  Utils.ceil_div(memory.size, 32)
end

#memory_store(start, size, data) ⇒ Object

store data to memory



59
60
61
62
63
# File 'lib/ciri/evm/machine_state.rb', line 59

def memory_store(start, size, data)
  if size > 0 && start < memory.size && start + size - 1 < memory.size
    memory[start..(start + size - 1)] = Serialize.serialize(data).rjust(size, "\x00".b)
  end
end

#pop(type = nil) ⇒ Object

pop a item from stack



42
43
44
45
# File 'lib/ciri/evm/machine_state.rb', line 42

def pop(type = nil)
  item = stack.shift
  item && Serialize.deserialize(type, item)
end

#pop_list(count, type = nil) ⇒ Object

fetch a list of items from stack



37
38
39
# File 'lib/ciri/evm/machine_state.rb', line 37

def pop_list(count, type = nil)
  count.times.map {pop(type)}
end

#push(item) ⇒ Object

push into stack



54
55
56
# File 'lib/ciri/evm/machine_state.rb', line 54

def push(item)
  stack.unshift(item)
end