ytl 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/ytl.rb +46 -7
- data/lib/ytl/accmem.rb +254 -55
- data/lib/ytl/macro.rb +20 -2
- data/lib/ytl/thread.rb +251 -0
- data/runtime/prelude.rb +65 -2
- data/runtime/thread.rb +27 -0
- data/runtime/type.rb +2 -0
- data/test/bar.rb +8 -0
- data/test/basictest.rb +6 -0
- data/test/breaktest.rb +22 -8
- data/test/exttest.rb +21 -7
- data/test/foo.rb +14 -0
- data/test/macrotest.rb +9 -6
- data/test/simple.rb +6 -0
- data/test/th_nested.rb +31 -0
- data/test/threadfib.rb +37 -0
- data/test/threadtest.rb +41 -0
- data/test/varargtest.rb +7 -0
- metadata +20 -18
data/lib/ytl.rb
CHANGED
@@ -9,7 +9,7 @@ include YTLJit
|
|
9
9
|
module YTL
|
10
10
|
include YTLJit
|
11
11
|
|
12
|
-
VERSION = "0.0.
|
12
|
+
VERSION = "0.0.5"
|
13
13
|
|
14
14
|
ISEQ_OPTS = {
|
15
15
|
:peephole_optimization => true,
|
@@ -33,6 +33,10 @@ module YTL
|
|
33
33
|
opt.on('--disp-signature', 'Display signature of method') do |f|
|
34
34
|
ytlopt[:disp_signature] = f
|
35
35
|
end
|
36
|
+
|
37
|
+
opt.on('--insert-signature-comment', 'insert comment of signature') do |f|
|
38
|
+
ytlopt[:insert_signature_comment] = f
|
39
|
+
end
|
36
40
|
|
37
41
|
opt.on('--dump-context', 'Dump context(registor/stack) for debug') do |f|
|
38
42
|
ytlopt[:dump_context] = f
|
@@ -76,8 +80,8 @@ module YTL
|
|
76
80
|
prelude = File.join(File.dirname(__FILE__), "..", "runtime", "prelude.rb")
|
77
81
|
rf = File.read(prelude)
|
78
82
|
prog = eval(rf)
|
79
|
-
is = RubyVM::InstructionSequence.compile(prog,
|
80
|
-
"",
|
83
|
+
is = RubyVM::InstructionSequence.compile(prog, prelude,
|
84
|
+
"", 1, ISEQ_OPTS).to_a
|
81
85
|
VMLib::InstSeqTree.new(nil, is)
|
82
86
|
end
|
83
87
|
|
@@ -106,7 +110,7 @@ module YTL
|
|
106
110
|
|
107
111
|
tnode = nil
|
108
112
|
is = RubyVM::InstructionSequence.compile(prog, ARGV[0],
|
109
|
-
"",
|
113
|
+
"", 1, ISEQ_OPTS).to_a
|
110
114
|
iseq = VMLib::InstSeqTree.new(nil, is)
|
111
115
|
iseqs = [prelude_iseq, iseq]
|
112
116
|
|
@@ -118,6 +122,7 @@ module YTL
|
|
118
122
|
tnode.collect_info(ci_context)
|
119
123
|
|
120
124
|
dmylit = VM::Node::LiteralNode.new(tnode, nil)
|
125
|
+
dmylit2 = VM::Node::LiteralNode.new(tnode, Object.new)
|
121
126
|
arg = [dmylit, dmylit, dmylit]
|
122
127
|
sig = []
|
123
128
|
arg.each do |ele|
|
@@ -150,8 +155,8 @@ module YTL
|
|
150
155
|
rf = File.read(fn)
|
151
156
|
prog = eval(rf)
|
152
157
|
progs.push prog
|
153
|
-
is = RubyVM::InstructionSequence.compile(prog,
|
154
|
-
"",
|
158
|
+
is = RubyVM::InstructionSequence.compile(prog, fn,
|
159
|
+
"", 1, ISEQ_OPTS).to_a
|
155
160
|
iseq = VMLib::InstSeqTree.new(nil, is)
|
156
161
|
tr = VM::YARVTranslatorCRubyObject.new([iseq])
|
157
162
|
tr_context.current_file_name = fn
|
@@ -159,6 +164,7 @@ module YTL
|
|
159
164
|
end
|
160
165
|
|
161
166
|
tnode = nil
|
167
|
+
progarray = nil
|
162
168
|
case File.extname(ARGV[0])
|
163
169
|
when ".ytl"
|
164
170
|
File.open(ARGV[0]) do |fp|
|
@@ -172,8 +178,11 @@ module YTL
|
|
172
178
|
|
173
179
|
when ".rb"
|
174
180
|
prog = File.read(ARGV[0])
|
181
|
+
if options[:insert_signature_comment] then
|
182
|
+
progarray = prog.split(/\n/)
|
183
|
+
end
|
175
184
|
is = RubyVM::InstructionSequence.compile(prog, ARGV[0],
|
176
|
-
"",
|
185
|
+
"", 1, ISEQ_OPTS).to_a
|
177
186
|
iseq = VMLib::InstSeqTree.new(nil, is)
|
178
187
|
if options[:dump_yarv] then
|
179
188
|
pp iseq
|
@@ -184,6 +193,9 @@ module YTL
|
|
184
193
|
tr_context.current_file_name = ARGV[0]
|
185
194
|
tnode = tr.translate(tr_context)
|
186
195
|
end
|
196
|
+
$0 = ARGV[0]
|
197
|
+
file_name = ARGV[0]
|
198
|
+
ARGV.shift
|
187
199
|
|
188
200
|
ci_context = VM::CollectInfoContext.new(tnode)
|
189
201
|
ci_context.options = options
|
@@ -194,6 +206,7 @@ module YTL
|
|
194
206
|
end
|
195
207
|
|
196
208
|
dmylit = VM::Node::LiteralNode.new(tnode, nil)
|
209
|
+
dmylit2 = VM::Node::LiteralNode.new(tnode, Object.new)
|
197
210
|
arg = [dmylit, dmylit, dmylit]
|
198
211
|
sig = []
|
199
212
|
arg.each do |ele|
|
@@ -230,6 +243,32 @@ module YTL
|
|
230
243
|
tnode.code_space.disassemble
|
231
244
|
end
|
232
245
|
|
246
|
+
if options[:insert_signature_comment] then
|
247
|
+
progarray.each_with_index do |lin, lno|
|
248
|
+
if cinfos = c_context.comment[file_name][lno] # and cinfo[0] then
|
249
|
+
cinfos.each do |cinfo|
|
250
|
+
case cinfo[0]
|
251
|
+
when 1
|
252
|
+
print "# #{cinfo[1]} \n"
|
253
|
+
cinfo[2..-1].each do |sig, res|
|
254
|
+
print "# #{sig[3..-1]} -> #{res.inspect} \n"
|
255
|
+
print "# self #{sig[2].inspect} \n"
|
256
|
+
print "# block #{sig[1].inspect} \n"
|
257
|
+
print "# \n"
|
258
|
+
end
|
259
|
+
when 2
|
260
|
+
print "# #{cinfo[1]} #{cinfo[2].inspect} \n"
|
261
|
+
when 3
|
262
|
+
if cinfo[1] == :local_export then
|
263
|
+
print "# please do't unroll stack \n"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
print lin, "\n"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
233
272
|
tcs = tnode.code_space
|
234
273
|
STDOUT.flush
|
235
274
|
if !options[:compile_only] then
|
data/lib/ytl/accmem.rb
CHANGED
@@ -7,31 +7,15 @@ end
|
|
7
7
|
module YTLJit
|
8
8
|
module VM
|
9
9
|
module Node
|
10
|
-
|
11
|
-
|
10
|
+
|
11
|
+
module AccMemUtil
|
12
12
|
include SendUtil
|
13
13
|
include X86
|
14
14
|
include X64
|
15
15
|
|
16
|
-
add_special_send_node :[]
|
17
|
-
|
18
|
-
def fill_result_cache(context)
|
19
|
-
slf = @arguments[2]
|
20
|
-
slfval = @arguments[2].get_constant_value
|
21
|
-
if slfval then
|
22
|
-
slfval =slfval[0]
|
23
|
-
|
24
|
-
idxval = @arguments[3].get_constant_value
|
25
|
-
if idxval then
|
26
|
-
idxval = idxval[0]
|
27
|
-
@result_cache = slfval[idxval]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context
|
32
|
-
end
|
33
|
-
|
34
16
|
def collect_candidate_type_regident(context, slf)
|
17
|
+
cursig = context.to_signature
|
18
|
+
@arguments[3].decide_type_once(cursig)
|
35
19
|
if slf.ruby_type <= YTL::Memory then
|
36
20
|
kind = @arguments[4]
|
37
21
|
kvalue = kind.get_constant_value
|
@@ -42,17 +26,20 @@ module YTLJit
|
|
42
26
|
case kvalue
|
43
27
|
when :char, :word, :dword, :machine_word
|
44
28
|
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
45
|
-
add_type(
|
29
|
+
add_type(cursig, fixtype)
|
46
30
|
|
47
31
|
when :float
|
48
32
|
floattype = RubyType::BaseType.from_ruby_class(Float)
|
49
|
-
add_type(
|
33
|
+
add_type(cursig, floattype)
|
50
34
|
|
51
35
|
when AsmType::StructMember
|
52
36
|
if kvalue.type.is_a?(AsmType::Scalar) then
|
53
37
|
if kvalue.type.kind == :int then
|
54
38
|
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
55
|
-
add_type(
|
39
|
+
add_type(cursig, ttype)
|
40
|
+
elsif kvalue.type.kind == :float then
|
41
|
+
ttype = RubyType::BaseType.from_ruby_class(Float)
|
42
|
+
add_type(cursig, ttype)
|
56
43
|
else
|
57
44
|
raise "Unkown type #{kvalue.type} #{kvalue.type.kind}"
|
58
45
|
end
|
@@ -63,7 +50,7 @@ module YTLJit
|
|
63
50
|
when AsmType::Scalar
|
64
51
|
if kvalue.kind == :int then
|
65
52
|
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
66
|
-
add_type(
|
53
|
+
add_type(cursig, ttype)
|
67
54
|
|
68
55
|
else
|
69
56
|
raise "Unkown type"
|
@@ -76,7 +63,7 @@ module YTLJit
|
|
76
63
|
|
77
64
|
else
|
78
65
|
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
79
|
-
add_type(
|
66
|
+
add_type(cursig, fixtype)
|
80
67
|
end
|
81
68
|
|
82
69
|
context
|
@@ -85,7 +72,7 @@ module YTLJit
|
|
85
72
|
slf.ruby_type <= AsmType::Array then
|
86
73
|
tt = AsmType::PointedData
|
87
74
|
pointedtype = RubyType::BaseType.from_ruby_class(tt)
|
88
|
-
add_type(
|
75
|
+
add_type(cursig, pointedtype)
|
89
76
|
context
|
90
77
|
|
91
78
|
elsif slf.ruby_type <= AsmType::Struct or
|
@@ -93,7 +80,7 @@ module YTLJit
|
|
93
80
|
slf.ruby_type <= AsmType::StructMember then
|
94
81
|
tt = AsmType::StructMember
|
95
82
|
stmemtype = RubyType::BaseType.from_ruby_class(tt)
|
96
|
-
add_type(
|
83
|
+
add_type(cursig, stmemtype)
|
97
84
|
context
|
98
85
|
|
99
86
|
else
|
@@ -101,45 +88,165 @@ module YTLJit
|
|
101
88
|
end
|
102
89
|
end
|
103
90
|
|
104
|
-
def
|
91
|
+
def gen_read_mem(context, type)
|
92
|
+
size = type.size
|
93
|
+
asm = context.assembler
|
94
|
+
case type.kind
|
95
|
+
when :int
|
96
|
+
case size
|
97
|
+
when 8
|
98
|
+
asm.with_retry do
|
99
|
+
if context.ret_reg != RAX then
|
100
|
+
asm.mov(RAX, context.ret_reg)
|
101
|
+
end
|
102
|
+
asm.mov(RAX, INDIRECT_RAX)
|
103
|
+
end
|
104
|
+
context.ret_reg = RAX
|
105
|
+
|
106
|
+
when 4
|
107
|
+
asm.with_retry do
|
108
|
+
if context.ret_reg != EAX then
|
109
|
+
asm.mov(EAX, context.ret_reg)
|
110
|
+
end
|
111
|
+
asm.mov(EAX, INDIRECT_EAX)
|
112
|
+
end
|
113
|
+
context.ret_reg = EAX
|
114
|
+
|
115
|
+
when 2
|
116
|
+
asm.with_retry do
|
117
|
+
asm.mov(AL, context.ret_reg)
|
118
|
+
asm.mov(AL, INDIRECT_AL)
|
119
|
+
end
|
120
|
+
context.ret_reg = EAX
|
121
|
+
|
122
|
+
else
|
123
|
+
raise "Unkown Scalar size #{kvalue}"
|
124
|
+
end
|
125
|
+
|
126
|
+
when :float
|
127
|
+
case size
|
128
|
+
when 8
|
129
|
+
asm.with_retry do
|
130
|
+
if context.ret_reg != RAX then
|
131
|
+
asm.mov(RAX, context.ret_reg)
|
132
|
+
end
|
133
|
+
asm.movsd(RETFR, INDIRECT_RAX)
|
134
|
+
end
|
135
|
+
context.ret_reg = RETFR
|
136
|
+
|
137
|
+
when 4
|
138
|
+
asm.with_retry do
|
139
|
+
if context.ret_reg != EAX then
|
140
|
+
asm.mov(EAX, context.ret_reg)
|
141
|
+
end
|
142
|
+
asm.movss(RETFR, INDIRECT_EAX)
|
143
|
+
end
|
144
|
+
context.ret_reg = RETFR
|
145
|
+
|
146
|
+
else
|
147
|
+
raise "Unkown Scalar size #{kvalue}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
105
151
|
context
|
106
152
|
end
|
107
153
|
|
108
|
-
def
|
154
|
+
def gen_write_mem(context, type)
|
155
|
+
size = type.size
|
109
156
|
asm = context.assembler
|
110
|
-
case
|
111
|
-
when
|
112
|
-
|
113
|
-
|
114
|
-
|
157
|
+
case type.kind
|
158
|
+
when :int
|
159
|
+
case size
|
160
|
+
when 8
|
161
|
+
asm.with_retry do
|
162
|
+
if context.ret_reg != RAX then
|
163
|
+
asm.mov(RAX, context.ret_reg)
|
164
|
+
end
|
165
|
+
asm.mov(INDIRECT_TMPR2, RAX)
|
166
|
+
end
|
167
|
+
context.ret_reg = RAX
|
168
|
+
|
169
|
+
when 4
|
170
|
+
asm.with_retry do
|
171
|
+
if context.ret_reg != EAX then
|
172
|
+
asm.mov(EAX, context.ret_reg)
|
173
|
+
end
|
174
|
+
asm.mov(INDIRECT_TMPR2, EAX)
|
115
175
|
end
|
116
|
-
|
176
|
+
context.ret_reg = EAX
|
177
|
+
|
178
|
+
when 2
|
179
|
+
asm.with_retry do
|
180
|
+
asm.mov(AL, context.ret_reg)
|
181
|
+
asm.mov(INDIRECT_TMPR2, AL)
|
182
|
+
end
|
183
|
+
context.ret_reg = EAX
|
184
|
+
|
185
|
+
else
|
186
|
+
raise "Unkown Scalar size #{kvalue}"
|
117
187
|
end
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
188
|
+
|
189
|
+
when :float
|
190
|
+
case size
|
191
|
+
when 8
|
192
|
+
asm.with_retry do
|
193
|
+
if context.ret_reg != RETFR then
|
194
|
+
asm.mov(RETFR, context.ret_reg)
|
195
|
+
end
|
196
|
+
asm.movsd(INDIRECT_TMPR2, RETFR)
|
124
197
|
end
|
125
|
-
|
198
|
+
context.ret_reg = RETFR
|
199
|
+
|
200
|
+
when 4
|
201
|
+
asm.with_retry do
|
202
|
+
if context.ret_reg != RETFR then
|
203
|
+
asm.mov(RETFR, context.ret_reg)
|
204
|
+
end
|
205
|
+
asm.movss(INDIRECT_TMPR2, RETFR)
|
206
|
+
end
|
207
|
+
context.ret_reg = RETFR
|
208
|
+
|
209
|
+
else
|
210
|
+
raise "Unkown Scalar size #{kvalue}"
|
126
211
|
end
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
212
|
+
end
|
213
|
+
|
214
|
+
context
|
215
|
+
end
|
216
|
+
|
217
|
+
def fill_result_cache(context)
|
218
|
+
slf = @arguments[2]
|
219
|
+
slfval = @arguments[2].get_constant_value
|
220
|
+
if slfval then
|
221
|
+
slfval =slfval[0]
|
222
|
+
|
223
|
+
idxval = @arguments[3].get_constant_value
|
224
|
+
if idxval then
|
225
|
+
idxval = idxval[0]
|
226
|
+
@result_cache = slfval[idxval]
|
133
227
|
end
|
134
|
-
context.ret_reg = EAX
|
135
|
-
|
136
|
-
else
|
137
|
-
raise "Unkown Scalar size #{kvalue}"
|
138
228
|
end
|
139
229
|
|
140
230
|
context
|
141
231
|
end
|
142
|
-
|
232
|
+
end
|
233
|
+
|
234
|
+
class SendElementRefMemoryNode<SendElementRefNode
|
235
|
+
include AccMemUtil
|
236
|
+
include SendUtil
|
237
|
+
include X86
|
238
|
+
include X64
|
239
|
+
|
240
|
+
add_special_send_node :[]
|
241
|
+
|
242
|
+
def collect_candidate_type_regident(context, slf)
|
243
|
+
super
|
244
|
+
end
|
245
|
+
|
246
|
+
def compile_ref_scalar(context, typeobj)
|
247
|
+
context
|
248
|
+
end
|
249
|
+
|
143
250
|
def compile(context)
|
144
251
|
slf = @arguments[2]
|
145
252
|
slf.decide_type_once(context.to_signature)
|
@@ -182,13 +289,16 @@ module YTLJit
|
|
182
289
|
context.ret_reg = RETFR
|
183
290
|
|
184
291
|
when AsmType::Scalar
|
185
|
-
context = gen_read_mem(context, kvalue
|
292
|
+
context = gen_read_mem(context, kvalue)
|
186
293
|
|
187
294
|
when AsmType::StructMember
|
188
295
|
typeobj = kvalue.type
|
189
296
|
case typeobj
|
190
297
|
when AsmType::Scalar
|
191
|
-
|
298
|
+
asm.with_retry do
|
299
|
+
asm.add(context.ret_reg, kvalue.offset)
|
300
|
+
end
|
301
|
+
context = gen_read_mem(context, typeobj)
|
192
302
|
|
193
303
|
else
|
194
304
|
raise "Unkown Struct Member type #{kvalue}"
|
@@ -231,6 +341,95 @@ module YTLJit
|
|
231
341
|
end
|
232
342
|
end
|
233
343
|
|
344
|
+
class SendElementAssignMemoryNode<SendElementAssignNode
|
345
|
+
include AccMemUtil
|
346
|
+
include SendUtil
|
347
|
+
include X86
|
348
|
+
include X64
|
349
|
+
|
350
|
+
add_special_send_node :[]=
|
351
|
+
|
352
|
+
def collect_candidate_type_regident(context, slf)
|
353
|
+
# value to set
|
354
|
+
if slf.ruby_type <= YTL::Memory then
|
355
|
+
context = @arguments[5].collect_candidate_type(context)
|
356
|
+
end
|
357
|
+
super
|
358
|
+
end
|
359
|
+
|
360
|
+
def compile(context)
|
361
|
+
slf = @arguments[2]
|
362
|
+
slf.decide_type_once(context.to_signature)
|
363
|
+
if slf.type.ruby_type <= YTL::Memory then
|
364
|
+
asm = context.assembler
|
365
|
+
|
366
|
+
kind = @arguments[4]
|
367
|
+
kvalue = nil
|
368
|
+
case kind
|
369
|
+
when LiteralNode
|
370
|
+
kvalue = kind.value
|
371
|
+
|
372
|
+
else
|
373
|
+
context = kind.compile(context)
|
374
|
+
if context.ret_reg.is_a?(OpVarImmidiateAddress) then
|
375
|
+
objid = (context.ret_reg.value >> 1)
|
376
|
+
kvalue = ObjectSpace._id2ref(objid)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
context = @arguments[3].compile(context)
|
381
|
+
context.start_using_reg(TMPR2)
|
382
|
+
asm.with_retry do
|
383
|
+
asm.mov(TMPR2, context.ret_reg)
|
384
|
+
end
|
385
|
+
context = @arguments[5].compile(context)
|
386
|
+
|
387
|
+
case kvalue
|
388
|
+
when :machine_word
|
389
|
+
asm.with_retry do
|
390
|
+
if context.ret_reg != RETR then
|
391
|
+
asm.mov(RETR, context.ret_reg)
|
392
|
+
end
|
393
|
+
asm.mov(INDIRECT_TMPR2, RETR)
|
394
|
+
end
|
395
|
+
context.ret_reg = RETR
|
396
|
+
|
397
|
+
when :float
|
398
|
+
asm.with_retry do
|
399
|
+
if context.ret_reg != RETFR then
|
400
|
+
asm.mov(RETFR, context.ret_reg)
|
401
|
+
end
|
402
|
+
asm.mov(INDIRECT_TMPR, RETFR)
|
403
|
+
end
|
404
|
+
context.ret_reg = RETFR
|
405
|
+
|
406
|
+
when AsmType::Scalar
|
407
|
+
context = gen_write_mem(context, kvalue)
|
408
|
+
|
409
|
+
when AsmType::StructMember
|
410
|
+
typeobj = kvalue.type
|
411
|
+
case typeobj
|
412
|
+
when AsmType::Scalar
|
413
|
+
asm.with_retry do
|
414
|
+
asm.add(TMPR2, kvalue.offset)
|
415
|
+
end
|
416
|
+
context = gen_write_mem(context, typeobj)
|
417
|
+
|
418
|
+
else
|
419
|
+
raise "Unkown Struct Member type #{kvalue}"
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context.ret_node = self
|
424
|
+
context.end_using_reg(TMPR2)
|
425
|
+
|
426
|
+
@body.compile(context)
|
427
|
+
else
|
428
|
+
super
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
234
433
|
class SendNewArenaNode<SendNewNode
|
235
434
|
add_special_send_node :new
|
236
435
|
|