Class: SyntaxTree::YARV::Disassembler

Inherits:
Object
  • Object
show all
Defined in:
lib/syntax_tree/yarv/disassembler.rb

Defined Under Namespace

Classes: Squished

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(current_iseq = nil) ⇒ Disassembler

Returns a new instance of Disassembler.



46
47
48
49
50
51
52
# File 'lib/syntax_tree/yarv/disassembler.rb', line 46

def initialize(current_iseq = nil)
  @output = StringIO.new
  @queue = []

  @current_prefix = ""
  @current_iseq = current_iseq
end

Instance Attribute Details

#current_iseqObject

Returns the value of attribute current_iseq.



44
45
46
# File 'lib/syntax_tree/yarv/disassembler.rb', line 44

def current_iseq
  @current_iseq
end

#current_prefixObject (readonly)

Returns the value of attribute current_prefix.



43
44
45
# File 'lib/syntax_tree/yarv/disassembler.rb', line 43

def current_prefix
  @current_prefix
end

#outputObject (readonly)

Returns the value of attribute output.



41
42
43
# File 'lib/syntax_tree/yarv/disassembler.rb', line 41

def output
  @output
end

#queueObject (readonly)

Returns the value of attribute queue.



41
42
43
# File 'lib/syntax_tree/yarv/disassembler.rb', line 41

def queue
  @queue
end

Instance Method Details

#calldata(value) ⇒ Object

Helpers for various instructions



58
59
60
# File 'lib/syntax_tree/yarv/disassembler.rb', line 58

def calldata(value)
  value.inspect
end

#enqueue(iseq) ⇒ Object



62
63
64
# File 'lib/syntax_tree/yarv/disassembler.rb', line 62

def enqueue(iseq)
  queue << iseq
end

#event(name) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/syntax_tree/yarv/disassembler.rb', line 66

def event(name)
  case name
  when :RUBY_EVENT_B_CALL
    "Bc"
  when :RUBY_EVENT_B_RETURN
    "Br"
  when :RUBY_EVENT_CALL
    "Ca"
  when :RUBY_EVENT_CLASS
    "Cl"
  when :RUBY_EVENT_END
    "En"
  when :RUBY_EVENT_LINE
    "Li"
  when :RUBY_EVENT_RETURN
    "Re"
  else
    raise "Unknown event: #{name}"
  end
end

#format!Object

Entrypoints



116
117
118
119
120
121
# File 'lib/syntax_tree/yarv/disassembler.rb', line 116

def format!
  while (@current_iseq = queue.shift)
    output << "\n" if output.pos > 0
    format_iseq(@current_iseq)
  end
end

#format_insns!(insns, length = 0) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/syntax_tree/yarv/disassembler.rb', line 123

def format_insns!(insns, length = 0)
  events = []
  lines = []

  insns.each do |insn|
    case insn
    when Integer
      lines << insn
    when Symbol
      events << event(insn)
    when InstructionSequence::Label
      # skip
    else
      output << "#{current_prefix}%04d " % length

      disasm = insn.disasm(self)
      output << disasm

      if lines.any?
        output << " " * (65 - disasm.length) if disasm.length < 65
      elsif events.any?
        output << " " * (39 - disasm.length) if disasm.length < 39
      end

      if lines.any?
        output << "(%4d)" % lines.last
        lines.clear
      end

      if events.any?
        output << "[#{events.join}]"
        events.clear
      end

      # A hook here to allow for custom formatting of instructions after
      # the main body has been processed.
      yield insn, length if block_given?

      output << "\n"
      length += insn.length
    end
  end
end

#inline_storage(cache) ⇒ Object



87
88
89
# File 'lib/syntax_tree/yarv/disassembler.rb', line 87

def inline_storage(cache)
  "<is:#{cache}>"
end

#instruction(name, operands = []) ⇒ Object



91
92
93
# File 'lib/syntax_tree/yarv/disassembler.rb', line 91

def instruction(name, operands = [])
  operands.empty? ? name : "%-38s %s" % [name, operands.join(", ")]
end

#label(value) ⇒ Object



95
96
97
# File 'lib/syntax_tree/yarv/disassembler.rb', line 95

def label(value)
  value.name["label_".length..]
end

#local(index, explicit: nil, implicit: nil) ⇒ Object



99
100
101
102
103
104
105
106
# File 'lib/syntax_tree/yarv/disassembler.rb', line 99

def local(index, explicit: nil, implicit: nil)
  current = current_iseq
  (explicit || implicit).times { current = current.parent_iseq }

  value = "#{current.local_table.name_at(index)}@#{index}"
  value << ", #{explicit}" if explicit
  value
end

#object(value) ⇒ Object



108
109
110
# File 'lib/syntax_tree/yarv/disassembler.rb', line 108

def object(value)
  value.inspect
end


167
168
169
# File 'lib/syntax_tree/yarv/disassembler.rb', line 167

def print(string)
  output.print(string)
end

#puts(string) ⇒ Object



171
172
173
# File 'lib/syntax_tree/yarv/disassembler.rb', line 171

def puts(string)
  output.puts(string)
end

#stringObject



175
176
177
# File 'lib/syntax_tree/yarv/disassembler.rb', line 175

def string
  output.string
end

#with_prefix(value) ⇒ Object



179
180
181
182
183
184
185
186
187
188
# File 'lib/syntax_tree/yarv/disassembler.rb', line 179

def with_prefix(value)
  previous = @current_prefix

  begin
    @current_prefix = value
    yield value
  ensure
    @current_prefix = previous
  end
end