class Mirrors::ISeqVisitor
ISeqVisitor
is an abstract class that knows how to walk methods and call the visit() method for each instruction. Internally it tracks the state of the current @pc, @line, and @label during the walk.
Attributes
class_refs[R]
field_refs[R]
iseq[R]
method_refs[R]
Public Instance Methods
call(method)
click to toggle source
visit all the instructions in the supplied method
# File lib/mirrors/visitors/iseq_visitor.rb, line 13 def call(method) @method = method @iseq = method.native_code # extract fields from iseq @magic, @major_version, @minor_version, @format_type, @misc, @label, @path, @absolute_path, @first_lineno, @type, @locals, @params, @catch_table, @bytecode = @iseq.to_a # walk state @pc = 0 # program counter @label # current label walk self end
visit(_bytecode)
click to toggle source
iterator call once for each opcode
# File lib/mirrors/visitors/iseq_visitor.rb, line 41 def visit(_bytecode) raise NotImplementedError, "subclass responsibility" end
Private Instance Methods
unrecognized_bytecode(bc)
click to toggle source
emit diagnostics and signal that an unrecognized opcode was encountered
# File lib/mirrors/visitors/iseq_visitor.rb, line 74 def unrecognized_bytecode(bc) puts "-----------------bytecode ---------------------" puts "bytecode=#{bc} clazz=#{bc.class}" puts "---------------- disassembly ------------------" puts @iseq.disasm puts "---------------- bytecode ------------------" pp @bytecode raise "Urecognized bytecode:#{bc} at index:#{@pc}" end
walk()
click to toggle source
walk the opcodes
# File lib/mirrors/visitors/iseq_visitor.rb, line 48 def walk return unless @bytecode # C extensions have no bytecode @pc = 0 @label = nil @bytecode.each_with_index do |bc| if (bc.class == Integer || bc.class == Fixnum) @line = bc # bare line number next # line numbers are not executable elsif bc.class == Symbol @label = bc next # labels are not executable elsif bc.class == Array @opcode = VM::InstructionSequence::Instruction.id2insn_no(bc.first) unrecognized_bytecode(bc) unless @opcode visit(bc) @pc += VM::InstructionSequence::Instruction.insn_no2size(@opcode) else unrecognized_bytecode(bc) end end end