Class: SystemNavigation::InstructionStream::Instruction

Inherits:
Object
  • Object
show all
Defined in:
lib/system_navigation/instruction_stream/instruction.rb,
lib/system_navigation/instruction_stream/instruction/attr_instruction.rb

Overview

Since:

  • 0.1.0

Direct Known Subclasses

AttrInstruction

Defined Under Namespace

Classes: AttrInstruction, AttrReaderInstruction, AttrWriterInstruction

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(str) ⇒ Instruction

Returns a new instance of Instruction.

Since:

  • 0.1.0



8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 8

def initialize(str)
  @raw = StringScanner.new(str)
  @pos = nil
  @opcode = ''
  @operand = nil
  @evaling_str = nil
  @lineno = nil
  @op_id = nil
  @ivar = nil
  @gvar = nil
  @cvar = nil
  @service_instruction = false
end

Class Method Details

.parse(str) ⇒ Object

Since:

  • 0.1.0



4
5
6
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 4

def self.parse(str)
  self.new(str).parse
end

Instance Method Details

#accessing_cvar?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



129
130
131
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 129

def accessing_cvar?
  @opcode == 'getclassvariable' || @opcode == 'setclassvariable'
end

#accessing_gvar?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



125
126
127
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 125

def accessing_gvar?
  @opcode == 'getglobal' || @opcode == 'setglobal'
end

#accessing_ivar?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



121
122
123
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 121

def accessing_ivar?
  @opcode == 'getinstancevariable' || @opcode == 'setinstancevariable'
end

#duparrays?(str) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



204
205
206
207
208
209
210
211
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 204

def duparrays?(str)
  s = case str
      when Array, Hash then Regexp.escape(str.inspect)
      else str
      end

  !!(self.opcode == 'duparray' && @operand.match(/:#{s}[,\]]/))
end

#dynamically_reads_ivar?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



145
146
147
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 145

def dynamically_reads_ivar?
  self.op_id == 'instance_variable_get'
end

#dynamically_writes_ivar?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



149
150
151
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 149

def dynamically_writes_ivar?
  @op_id == 'instance_variable_set'
end

#evaling_strObject

Since:

  • 0.1.0



217
218
219
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 217

def evaling_str
  @evaling_str ||= @operand.sub!(/\A"(.+)"/, '\1')
end

#evals?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



169
170
171
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 169

def evals?
  self.op_id == 'eval'
end

#find_messageObject

Since:

  • 0.1.0



221
222
223
224
225
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 221

def find_message
  return unless sending?

  @op_id
end

#parseObject

Since:

  • 0.1.0



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 22

def parse
  return if parse_service_instruction

  parse_position
  parse_opcode
  parse_operand
  parse_lineno
  parse_op_id
  parse_var

  self
end

#parse_cvarObject

Since:

  • 0.1.0



112
113
114
115
116
117
118
119
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 112

def parse_cvar
  return unless accessing_cvar?

  cvar = StringScanner.new(@operand)
  @cvar = cvar.scan(/:[^,]+/)[1..-1].to_sym
  cvar.terminate
  @cvar
end

#parse_gvarObject

Since:

  • 0.1.0



103
104
105
106
107
108
109
110
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 103

def parse_gvar
  return unless accessing_gvar?

  gvar = StringScanner.new(@operand)
  @gvar = gvar.scan(/[^,]+/).to_sym
  gvar.terminate
  @gvar
end

#parse_ivarObject

Since:

  • 0.1.0



94
95
96
97
98
99
100
101
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 94

def parse_ivar
  return unless accessing_ivar?

  ivar = StringScanner.new(@operand)
  @ivar = ivar.scan(/:[^,]+/)[1..-1].to_sym
  ivar.terminate
  @ivar
end

#parse_linenoObject

Since:

  • 0.1.0



73
74
75
76
77
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 73

def parse_lineno
  n = @raw.scan(/[0-9]+/)
  @lineno = n.to_i if n
  @raw.skip(/\)/)
end

#parse_op_idObject

Since:

  • 0.1.0



79
80
81
82
83
84
85
86
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 79

def parse_op_id
  return unless sending?

  callinfo = StringScanner.new(@operand)
  callinfo.skip(/<callinfo!mid:/)
  @op_id = callinfo.scan(/\S+(?=,)/)
  callinfo.terminate
end

#parse_opcodeObject

Since:

  • 0.1.0



47
48
49
50
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 47

def parse_opcode
  @opcode = @raw.scan(/[a-zA-Z0-9_]+/)
  @raw.skip(/\s*/)
end

#parse_operandObject

Since:

  • 0.1.0



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 52

def parse_operand
  if @raw.check(/</)
    @operand = @raw.scan(/<.+>/)
  elsif @raw.check(/\[/)
    @operand = @raw.scan(/\[.*\]/)
  elsif @raw.check(/"/)
    @operand = @raw.scan(/".*"/)
  elsif @raw.check(%r{/})
    @operand = @raw.scan(%r{/.*/})
  else
    @operand = @raw.scan(/-?[0-9a-zA-Z:@_=.$]+/)

    if @raw.peek(1) == ','
      @operand << @raw.scan(/[^\(]*/).rstrip
    end
  end

  @raw.skip(/\s*\(?/)
  @raw.skip(/\s*/)
end

#parse_positionObject

Since:

  • 0.1.0



41
42
43
44
45
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 41

def parse_position
  n = @raw.scan(/[0-9]{4,6}/)
  @pos = n.to_i if n
  @raw.skip(/\s*/)
end

#parse_service_instructionObject

Since:

  • 0.1.0



35
36
37
38
39
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 35

def parse_service_instruction
  if @raw.peek(2) == '==' || @raw.peek(6) !~ /[0-9]{4,6} /
    @service_instruction = true
  end
end

#parse_varObject

Since:

  • 0.1.0



88
89
90
91
92
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 88

def parse_var
  parse_ivar
  parse_gvar
  parse_cvar
end

#putnils?(str) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



199
200
201
202
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 199

def putnils?(str)
  return false unless self.opcode == 'putnil'
  @operand == str.inspect
end

#putobjects?(str) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



188
189
190
191
192
193
194
195
196
197
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 188

def putobjects?(str)
  return false unless @opcode == 'putobject'

  s = (str.instance_of?(String) ? Regexp.escape(str) : str)

  return true if @operand.match(/(?::#{s}\z|\[.*:#{s},.*\])/)
  return true if @operand == str.inspect

  false
end

#putstrings?(str) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 173

def putstrings?(str)
  return false unless self.opcode == 'putstring'

  s = str.inspect

  return true if @operand == s || @operand == %|"#{s}"|
  if @operand.match(/(eval\()?.*:?#{str}[^[\w;]].*\)?/)
    return true
  else

  end

  false
end

#reads_cvar?(cvar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



161
162
163
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 161

def reads_cvar?(cvar)
  @opcode == 'getclassvariable' && @cvar == cvar
end

#reads_gvar?(gvar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



153
154
155
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 153

def reads_gvar?(gvar)
  @opcode == 'getglobal' && @gvar == gvar
end

#reads_ivar?(ivar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



137
138
139
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 137

def reads_ivar?(ivar)
  @opcode == 'getinstancevariable' && @ivar == ivar
end

#sends_msg?(message) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



213
214
215
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 213

def sends_msg?(message)
  !!(sending? && @op_id == message.to_s)
end

#vm_operative?Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



133
134
135
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 133

def vm_operative?
  @service_instruction == false
end

#writes_cvar?(cvar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



165
166
167
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 165

def writes_cvar?(cvar)
  @opcode == 'setclassvariable' && @cvar == cvar
end

#writes_gvar?(gvar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



157
158
159
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 157

def writes_gvar?(gvar)
  @opcode == 'setglobal' && @gvar == gvar
end

#writes_ivar?(ivar) ⇒ Boolean

Returns:

  • (Boolean)

Since:

  • 0.1.0



141
142
143
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 141

def writes_ivar?(ivar)
  @opcode == 'setinstancevariable' && @ivar == ivar
end