Class: YTLJit::Assembler
Constant Summary
collapse
- @@value_table_cache =
{}
- @@value_table_entity =
ValueSpace.new
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(out, gen = GeneratorExtend) ⇒ Assembler
Returns a new instance of Assembler.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# File 'lib/ytljit/asm.rb', line 105
def initialize(out, gen = GeneratorExtend)
@generator = gen.new(self)
@output_stream = out
@retry_mode = false
@step_mode = false
@asmsend_history = []
@after_patch_tab = []
@patched_num = 0
reset
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(mn, *args) ⇒ Object
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
# File 'lib/ytljit/asm.rb', line 244
def method_missing(mn, *args)
out = @generator.call_stephandler
store_outcode(out)
if @retry_mode == false then
case mn
when :call_with_arg
args.push(@generator.call_with_arg_get_argsize(*args))
end
@asmsend_history.push [mn, args]
end
add_var_value_retry_func(mn, args)
out = @generator.send(mn, *args)
if out.is_a?(Array) then
store_outcode(out[0])
else
store_outcode(out)
end
out
end
|
Instance Attribute Details
#after_patch_tab ⇒ Object
Returns the value of attribute after_patch_tab.
130
131
132
|
# File 'lib/ytljit/asm.rb', line 130
def after_patch_tab
@after_patch_tab
end
|
#current_address ⇒ Object
Returns the value of attribute current_address.
126
127
128
|
# File 'lib/ytljit/asm.rb', line 126
def current_address
@current_address
end
|
#generated_code ⇒ Object
Returns the value of attribute generated_code.
143
144
145
|
# File 'lib/ytljit/asm.rb', line 143
def generated_code
@generated_code
end
|
#generator ⇒ Object
Returns the value of attribute generator.
132
133
134
|
# File 'lib/ytljit/asm.rb', line 132
def generator
@generator
end
|
Returns the value of attribute offset.
128
129
130
|
# File 'lib/ytljit/asm.rb', line 128
def offset
@offset
end
|
#output_stream ⇒ Object
Returns the value of attribute output_stream.
129
130
131
|
# File 'lib/ytljit/asm.rb', line 129
def output_stream
@output_stream
end
|
#retry_mode ⇒ Object
Returns the value of attribute retry_mode.
131
132
133
|
# File 'lib/ytljit/asm.rb', line 131
def retry_mode
@retry_mode
end
|
#step_mode ⇒ Object
Returns the value of attribute step_mode.
127
128
129
|
# File 'lib/ytljit/asm.rb', line 127
def step_mode
@step_mode
end
|
Class Method Details
.get_value_table(out) ⇒ Object
101
102
103
|
# File 'lib/ytljit/asm.rb', line 101
def self.get_value_table(out)
[@@value_table_entity, @@value_table_cache]
end
|
.set_value_table(out) ⇒ Object
96
97
98
99
|
# File 'lib/ytljit/asm.rb', line 96
def self.set_value_table(out)
@@value_table_cache = {}
@@value_table_entity = out
end
|
Instance Method Details
#add_value_entry(val) ⇒ Object
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
# File 'lib/ytljit/asm.rb', line 186
def add_value_entry(val)
off= nil
unless off = @@value_table_cache[val] then
off = @@value_table_entity.current_pos
@@value_table_entity.emit([val.value].pack("Q"))
stfunc = lambda {
value_table_entity = get_value_table_entity
oldpos = value_table_entity.current_pos
value_table_entity.current_pos = off
value_table_entity.emit([val.value].pack("Q"))
value_table_entity.current_pos = oldpos
}
val.add_refer(stfunc)
@@value_table_cache[val] = off
end
@@value_table_entity.var_base_address(off)
end
|
#add_value_entry_no_cache(val) ⇒ Object
205
206
207
208
209
210
211
212
213
214
215
216
217
|
# File 'lib/ytljit/asm.rb', line 205
def add_value_entry_no_cache(val)
off = @@value_table_entity.current_pos
@@value_table_entity.emit([val.value].pack("Q"))
stfunc = lambda {
oldpos = @@value_table_entity.current_pos
@@value_table_entity.current_pos = off
@@value_table_entity.emit([val.value].pack("Q"))
@@value_table_entity.current_pos = oldpos
}
val.add_refer(stfunc)
@@value_table_entity.var_base_address(off)
end
|
#add_var_value_retry_func(mn, args) ⇒ Object
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
# File 'lib/ytljit/asm.rb', line 219
def add_var_value_retry_func(mn, args)
if args.any? {|e| e.is_a?(OpVarValueMixin) } and
@retry_mode == false then
offset = @offset
stfunc = lambda {
with_current_address(@output_stream.base_address + offset) {
orgretry_mode = @retry_mode
@retry_mode = :change_op
out = @generator.send(mn, *args)
if out.is_a?(Array)
@output_stream[offset] = out[0]
else
@output_stream[offset] = out
end
@retry_mode = orgretry_mode
}
}
args.each do |e|
if e.is_a?(OpVarValueMixin) then
e.add_refer(stfunc)
end
end
end
end
|
#get_value_table_entity ⇒ Object
182
183
184
|
# File 'lib/ytljit/asm.rb', line 182
def get_value_table_entity
@@value_table_entity
end
|
120
121
122
123
124
|
# File 'lib/ytljit/asm.rb', line 120
def reset
@current_address = @output_stream.base_address
@offset = 0
@patched_num = 0
end
|
#store_outcode(out) ⇒ Object
145
146
147
148
149
150
|
# File 'lib/ytljit/asm.rb', line 145
def store_outcode(out)
update_state(out)
@offset += out.bytesize
@output_stream.emit(out)
out
end
|
#update_state(out) ⇒ Object
152
153
154
155
|
# File 'lib/ytljit/asm.rb', line 152
def update_state(out)
@current_address += out.bytesize
out
end
|
#var_current_address ⇒ Object
134
135
136
137
138
139
140
141
|
# File 'lib/ytljit/asm.rb', line 134
def var_current_address
current_address = @current_address
func = lambda {
current_address
}
OpVarMemAddress.new(func)
end
|
#with_current_address(address) ⇒ Object
266
267
268
269
270
271
|
# File 'lib/ytljit/asm.rb', line 266
def with_current_address(address)
org_curret_address = self.current_address
self.current_address = address
yield
self.current_address = org_curret_address
end
|
#with_retry(&body) ⇒ Object
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
# File 'lib/ytljit/asm.rb', line 157
def with_retry(&body)
org_base_address = @output_stream.base_address
yield
org_retry_mode = @retry_mode
@retry_mode = :change_org
while org_base_address != @output_stream.base_address
org_base_address = @output_stream.base_address
reset
@output_stream.reset
@generator.funcarg_info.used_arg_tab = []
@generator.funcarg_info.area_allocate_pos = []
@asmsend_history.each do |arg|
send(arg[0], *arg[1])
end
@output_stream.update_refer
end
@after_patch_tab[@patched_num..-1].each do |patproc|
patproc.call
end
@patched_num = @after_patch_tab.size
@retry_mode = org_retry_mode
end
|