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.
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
# File 'lib/ytljit/asm.rb', line 70
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
# File 'lib/ytljit/asm.rb', line 180
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.
95
96
97
|
# File 'lib/ytljit/asm.rb', line 95
def after_patch_tab
@after_patch_tab
end
|
#current_address ⇒ Object
Returns the value of attribute current_address.
91
92
93
|
# File 'lib/ytljit/asm.rb', line 91
def current_address
@current_address
end
|
#generated_code ⇒ Object
Returns the value of attribute generated_code.
107
108
109
|
# File 'lib/ytljit/asm.rb', line 107
def generated_code
@generated_code
end
|
Returns the value of attribute offset.
93
94
95
|
# File 'lib/ytljit/asm.rb', line 93
def offset
@offset
end
|
#output_stream ⇒ Object
Returns the value of attribute output_stream.
94
95
96
|
# File 'lib/ytljit/asm.rb', line 94
def output_stream
@output_stream
end
|
#retry_mode ⇒ Object
Returns the value of attribute retry_mode.
96
97
98
|
# File 'lib/ytljit/asm.rb', line 96
def retry_mode
@retry_mode
end
|
#step_mode ⇒ Object
Returns the value of attribute step_mode.
92
93
94
|
# File 'lib/ytljit/asm.rb', line 92
def step_mode
@step_mode
end
|
Class Method Details
.get_value_table(out) ⇒ Object
66
67
68
|
# File 'lib/ytljit/asm.rb', line 66
def self.get_value_table(out)
[@@value_table_entity, @@value_table_cache]
end
|
.set_value_table(out) ⇒ Object
61
62
63
64
|
# File 'lib/ytljit/asm.rb', line 61
def self.set_value_table(out)
@@value_table_cache = {}
@@value_table_entity = out
end
|
Instance Method Details
#add_value_entry(val) ⇒ Object
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/ytljit/asm.rb', line 144
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"))
@@value_table_cache[val] = off
end
@@value_table_entity.var_base_address(off)
end
|
#add_var_value_retry_func(mn, args) ⇒ Object
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
# File 'lib/ytljit/asm.rb', line 155
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
|
85
86
87
88
89
|
# File 'lib/ytljit/asm.rb', line 85
def reset
@current_address = @output_stream.base_address
@offset = 0
@patched_num = 0
end
|
#store_outcode(out) ⇒ Object
109
110
111
112
113
114
|
# File 'lib/ytljit/asm.rb', line 109
def store_outcode(out)
update_state(out)
@offset += out.bytesize
@output_stream.emit(out)
out
end
|
#update_state(out) ⇒ Object
116
117
118
119
|
# File 'lib/ytljit/asm.rb', line 116
def update_state(out)
@current_address += out.bytesize
out
end
|
#var_current_address ⇒ Object
98
99
100
101
102
103
104
105
|
# File 'lib/ytljit/asm.rb', line 98
def var_current_address
current_address = @current_address
func = lambda {
current_address
}
OpVarMemAddress.new(func)
end
|
#with_current_address(address) ⇒ Object
202
203
204
205
206
207
|
# File 'lib/ytljit/asm.rb', line 202
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
# File 'lib/ytljit/asm.rb', line 121
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 do
org_base_address = @output_stream.base_address
reset
@output_stream.reset
@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
|