Class: SystemNavigation::InstructionStream::Decoder
- Inherits:
-
Object
- Object
- SystemNavigation::InstructionStream::Decoder
- Defined in:
- lib/system_navigation/instruction_stream/decoder.rb
Overview
Instance Method Summary collapse
- #cvar_read_scan(cvar) ⇒ Object
- #cvar_write_scan(cvar) ⇒ Object
- #gvar_read_scan(gvar) ⇒ Object
- #gvar_write_scan(gvar) ⇒ Object
-
#initialize(scanner) ⇒ Decoder
constructor
A new instance of Decoder.
- #ivar_read_scan(ivar) ⇒ Object
- #ivar_write_scan(ivar) ⇒ Object
- #literal_scan(literal) ⇒ Object
- #msg_send_scan(message) ⇒ Object
- #scan_for_sent_messages ⇒ Object
- #select_instructions(literal:, method_name: nil, &block) ⇒ Object
Constructor Details
#initialize(scanner) ⇒ Decoder
Returns a new instance of Decoder.
4 5 6 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 4 def initialize(scanner) @scanner = scanner end |
Instance Method Details
#cvar_read_scan(cvar) ⇒ Object
57 58 59 60 61 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 57 def cvar_read_scan(cvar) self.select_instructions(literal: cvar) do |_prev_prev, prev, instruction| next instruction if instruction.reads_cvar?(cvar) end end |
#cvar_write_scan(cvar) ⇒ Object
63 64 65 66 67 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 63 def cvar_write_scan(cvar) self.select_instructions(literal: cvar) do |prev_prev, prev, instruction| next instruction if instruction.writes_cvar?(cvar) end end |
#gvar_read_scan(gvar) ⇒ Object
45 46 47 48 49 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 45 def gvar_read_scan(gvar) self.select_instructions(literal: gvar) do |_prev_prev, prev, instruction| next instruction if instruction.reads_gvar?(gvar) end end |
#gvar_write_scan(gvar) ⇒ Object
51 52 53 54 55 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 51 def gvar_write_scan(gvar) self.select_instructions(literal: gvar) do |prev_prev, prev, instruction| next instruction if instruction.writes_gvar?(gvar) end end |
#ivar_read_scan(ivar) ⇒ Object
25 26 27 28 29 30 31 32 33 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 25 def ivar_read_scan(ivar) self.select_instructions(literal: ivar) do |_prev_prev, prev, instruction| next instruction if instruction.reads_ivar?(ivar) if instruction.dynamically_reads_ivar? && prev.putobjects?(ivar) next instruction end end end |
#ivar_write_scan(ivar) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 35 def ivar_write_scan(ivar) self.select_instructions(literal: ivar) do |prev_prev, prev, instruction| next instruction if instruction.writes_ivar?(ivar) if instruction.dynamically_writes_ivar? && prev_prev.putobjects?(ivar) next instruction end end end |
#literal_scan(literal) ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 69 def literal_scan(literal) name = @scanner.method.original_name self.select_instructions(method_name: name, literal: literal) do |_prev_prev, prev, instruction| if instruction.putobjects?(literal) || instruction.putnils?(literal) || instruction.duparrays?(literal) || instruction.putstrings?(literal) next instruction end end end |
#msg_send_scan(message) ⇒ Object
82 83 84 85 86 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 82 def msg_send_scan() self.select_instructions(literal: ) do |_prev_prev, prev, instruction| next instruction if instruction.sends_msg?() end end |
#scan_for_sent_messages ⇒ Object
88 89 90 91 92 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 88 def @scanner.iseqs(nil).map do |instruction| instruction. end.compact end |
#select_instructions(literal:, method_name: nil, &block) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/system_navigation/instruction_stream/decoder.rb', line 8 def select_instructions(literal:, method_name: nil, &block) instructions = @scanner.iseqs(method_name || literal) instructions.select.with_index do |instruction, i| prev = instructions[i - 1] prev_prev = instructions[i - 2] returned = block.call(prev_prev, prev, instruction) next instruction if returned next if !(instruction.evals? && prev.putstrings?(literal)) self.class.new(iseq_from_eval(prev, @scanner.method)). __send__(block.binding.eval('__method__'), literal).any? end end |