Class: SystemNavigation::InstructionStream::Instruction
- Inherits:
-
Object
- Object
- SystemNavigation::InstructionStream::Instruction
show all
- Defined in:
- lib/system_navigation/instruction_stream/instruction.rb,
lib/system_navigation/instruction_stream/instruction/attr_instruction.rb
Overview
Defined Under Namespace
Classes: AttrInstruction, AttrReaderInstruction, AttrWriterInstruction
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
Returns a new instance of Instruction.
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
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
129
130
131
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 129
def accessing_cvar?
@opcode == 'getclassvariable' || @opcode == 'setclassvariable'
end
|
#accessing_gvar? ⇒ Boolean
125
126
127
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 125
def accessing_gvar?
@opcode == 'getglobal' || @opcode == 'setglobal'
end
|
#accessing_ivar? ⇒ Boolean
121
122
123
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 121
def accessing_ivar?
@opcode == 'getinstancevariable' || @opcode == 'setinstancevariable'
end
|
#duparrays?(str) ⇒ Boolean
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
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
149
150
151
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 149
def dynamically_writes_ivar?
@op_id == 'instance_variable_set'
end
|
#evaling_str ⇒ Object
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
169
170
171
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 169
def evals?
self.op_id == 'eval'
end
|
#find_message ⇒ Object
221
222
223
224
225
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 221
def find_message
return unless sending?
@op_id
end
|
#parse ⇒ Object
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_cvar ⇒ Object
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_gvar ⇒ Object
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_ivar ⇒ Object
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_lineno ⇒ Object
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_id ⇒ Object
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_opcode ⇒ Object
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_operand ⇒ Object
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_position ⇒ Object
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_instruction ⇒ Object
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_var ⇒ Object
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
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
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
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
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
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
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
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
133
134
135
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 133
def vm_operative?
@service_instruction == false
end
|
#writes_cvar?(cvar) ⇒ Boolean
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
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
141
142
143
|
# File 'lib/system_navigation/instruction_stream/instruction.rb', line 141
def writes_ivar?(ivar)
@opcode == 'setinstancevariable' && @ivar == ivar
end
|