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/macro.rb
CHANGED
@@ -302,11 +302,17 @@ module YTLJit
|
|
302
302
|
def to_ruby(context)
|
303
303
|
arg = @parent.arguments
|
304
304
|
context.ret_code.last << "("
|
305
|
+
name = @name
|
306
|
+
callee = nil
|
305
307
|
if @parent.is_fcall or @parent.is_vcall then
|
306
|
-
|
308
|
+
callee = SendNode.get_macro_tab[name]
|
309
|
+
if callee then
|
310
|
+
name = ("ytl__eval_" + name.to_s).to_sym
|
311
|
+
end
|
312
|
+
context.ret_code.last << name.to_s
|
307
313
|
else
|
308
314
|
context = arg[2].to_ruby(context)
|
309
|
-
context.ret_code.last << ".#{
|
315
|
+
context.ret_code.last << ".#{name}"
|
310
316
|
end
|
311
317
|
if arg[3] then
|
312
318
|
context.ret_code.last << "("
|
@@ -324,6 +330,18 @@ module YTLJit
|
|
324
330
|
context = arg[1].to_ruby(context)
|
325
331
|
context.work_prefix.pop
|
326
332
|
end
|
333
|
+
if callee then
|
334
|
+
context.ret_code.last << "[0]"
|
335
|
+
callee.each do |rec, cele|
|
336
|
+
if cele.is_a?(BaseNode) then
|
337
|
+
SendNode.get_macro_tab[@name][rec] = true
|
338
|
+
tcontext = ToRubyContext.new
|
339
|
+
code = cele.to_ruby(tcontext).ret_code.last
|
340
|
+
proc = eval("lambda" + code)
|
341
|
+
SendNode.get_macro_tab[@name][rec] = proc
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
327
345
|
context.ret_code.last << ")\n"
|
328
346
|
context
|
329
347
|
end
|
data/lib/ytl/thread.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
module YTLJit
|
2
|
+
module VM
|
3
|
+
module TypeCodeGen
|
4
|
+
module YTLJitRuntimeThreadTypeBoxedCodeGen
|
5
|
+
include TypeUtil
|
6
|
+
def instance
|
7
|
+
ni = self.dup
|
8
|
+
ni.instance_eval { extend YTLJitRuntimeThreadTypeBoxedCodeGen }
|
9
|
+
ni.init
|
10
|
+
ni
|
11
|
+
end
|
12
|
+
|
13
|
+
def init
|
14
|
+
@element_type = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_accessor :element_type
|
18
|
+
|
19
|
+
def gen_copy(context)
|
20
|
+
context
|
21
|
+
end
|
22
|
+
|
23
|
+
def have_element?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
"{#{@ruby_type} self=#{@element_type.inspect}}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module Node
|
34
|
+
class SimpleVectorRefNode<BaseNode
|
35
|
+
def initialize(parent, offset, basereg)
|
36
|
+
super(parent)
|
37
|
+
@offset = offset
|
38
|
+
@base_reg = basereg
|
39
|
+
end
|
40
|
+
|
41
|
+
def collect_candidate_type(context)
|
42
|
+
context
|
43
|
+
end
|
44
|
+
|
45
|
+
def compile(context)
|
46
|
+
asm = context.assembler
|
47
|
+
siz = AsmType::MACHINE_WORD.size
|
48
|
+
src = OpIndirect.new(@base_reg, @offset * siz)
|
49
|
+
asm.with_retry do
|
50
|
+
asm.mov(TMPR, src)
|
51
|
+
end
|
52
|
+
context.ret_reg = TMPR
|
53
|
+
context.ret_node = self
|
54
|
+
context
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class SendThreadPselfNode<SendNode
|
59
|
+
add_special_send_node :pself
|
60
|
+
def collect_candidate_type_regident(context, slf)
|
61
|
+
cursig = context.to_signature
|
62
|
+
slfcls = @arguments[2].decide_type_once(cursig)
|
63
|
+
if slfcls.ruby_type == Runtime::Thread then
|
64
|
+
add_type(cursig, slfcls.element_type[nil][0])
|
65
|
+
context
|
66
|
+
else
|
67
|
+
super
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class SendThreadCselfNode<SendThreadPselfNode
|
73
|
+
add_special_send_node :cself
|
74
|
+
end
|
75
|
+
|
76
|
+
class SendThreadNewNode<SendNewArenaNode
|
77
|
+
include NodeUtil
|
78
|
+
include SendSingletonClassUtil
|
79
|
+
add_special_send_node :new
|
80
|
+
|
81
|
+
def initialize(parent, func, arguments, op_flag, seqno)
|
82
|
+
super
|
83
|
+
@yield_node = nil
|
84
|
+
@block_cs = CodeSpace.new
|
85
|
+
@block_args = []
|
86
|
+
@frame_info = search_frame_info
|
87
|
+
@arguments.each_with_index do |ele, idx|
|
88
|
+
nnode = nil
|
89
|
+
if idx != 1 then
|
90
|
+
nnode = SimpleVectorRefNode.new(self, idx + 1, TMPR2)
|
91
|
+
else
|
92
|
+
nnode = @arguments[1]
|
93
|
+
end
|
94
|
+
@block_args.push nnode
|
95
|
+
end
|
96
|
+
func = DirectBlockNode.new(self, @arguments[1])
|
97
|
+
@yield_node = SendNode.new(self, func, @block_args, 0, 0)
|
98
|
+
@modified_instance_var = nil
|
99
|
+
@curpare = [nil, []]
|
100
|
+
end
|
101
|
+
|
102
|
+
def collect_info(context)
|
103
|
+
context.modified_instance_var[:@_prev_self] ||= []
|
104
|
+
context.modified_instance_var[:@_prev_self].push @curpare
|
105
|
+
@modified_instance_var = context.modified_instance_var
|
106
|
+
@arguments.each do |arg|
|
107
|
+
context = arg.collect_info(context)
|
108
|
+
end
|
109
|
+
context = @func.collect_info(context)
|
110
|
+
@body.collect_info(context)
|
111
|
+
end
|
112
|
+
|
113
|
+
def collect_candidate_type_regident(context, slf)
|
114
|
+
slfcls = @arguments[2].get_constant_value
|
115
|
+
tt = RubyType::BaseType.from_ruby_class(slfcls[0])
|
116
|
+
if tt.ruby_type == Runtime::Thread then
|
117
|
+
cursig = context.to_signature
|
118
|
+
slfoff = @frame_info.real_offset(2)
|
119
|
+
slfnode = @frame_info.frame_layout[slfoff]
|
120
|
+
blknode = @arguments[1]
|
121
|
+
[@arguments[0], blknode, slfnode].zip(@block_args) do |bele, oele|
|
122
|
+
same_type(oele, bele, cursig, cursig, context)
|
123
|
+
end
|
124
|
+
|
125
|
+
yargs = @block_args
|
126
|
+
context = @yield_node.collect_candidate_type(context)
|
127
|
+
ysignat = @yield_node.signature(context)
|
128
|
+
context = blknode.collect_candidate_type(context, yargs, ysignat)
|
129
|
+
|
130
|
+
tt = RubyType::BaseType.from_ruby_class(Runtime::Thread)
|
131
|
+
add_type(cursig, tt)
|
132
|
+
joinsig = cursig.dup
|
133
|
+
joinsig[1] = RubyType::BaseType.from_ruby_class(NilClass)
|
134
|
+
joinsig[2] = tt
|
135
|
+
add_element_node(tt, cursig, slfnode, nil, context)
|
136
|
+
add_element_node(tt, ysignat, slfnode, nil, context)
|
137
|
+
same_type(slfnode, slfnode, ysignat, cursig, context)
|
138
|
+
add_element_node(tt, joinsig, slfnode, nil, context)
|
139
|
+
same_type(slfnode, slfnode, joinsig, cursig, context)
|
140
|
+
|
141
|
+
@curpare[0] = slfnode
|
142
|
+
if !@curpare[1].include?(cursig) then
|
143
|
+
@curpare[1].push cursig
|
144
|
+
end
|
145
|
+
|
146
|
+
return context
|
147
|
+
end
|
148
|
+
|
149
|
+
return super
|
150
|
+
end
|
151
|
+
|
152
|
+
def compile(context)
|
153
|
+
rect = @arguments[2].decide_type_once(context.to_signature)
|
154
|
+
rrtype = rect.ruby_type_raw
|
155
|
+
if rrtype.is_a?(ClassClassWrapper) then
|
156
|
+
rrtype = get_singleton_class_object(@arguments[2]).ruby_type
|
157
|
+
if rrtype == Runtime::Thread then
|
158
|
+
cursig = context.to_signature
|
159
|
+
|
160
|
+
# Generate block invoker
|
161
|
+
tcontext = context.dup
|
162
|
+
tcontext.set_code_space(@block_cs)
|
163
|
+
asm = tcontext.assembler
|
164
|
+
asm.with_retry do
|
165
|
+
asm.mov(TMPR, FUNC_ARG[0])
|
166
|
+
end
|
167
|
+
tcontext.start_using_reg(TMPR2)
|
168
|
+
asm.with_retry do
|
169
|
+
asm.mov(TMPR2, TMPR)
|
170
|
+
asm.mov(THEPR, INDIRECT_TMPR2)
|
171
|
+
end
|
172
|
+
tcontext = @yield_node.compile(tcontext)
|
173
|
+
tcontext.end_using_reg(TMPR2)
|
174
|
+
addr = lambda {
|
175
|
+
a = address_of('ytl_thread_exit')
|
176
|
+
$symbol_table[a] = 'yth_thread_exit'
|
177
|
+
a
|
178
|
+
}
|
179
|
+
thread_exit = OpVarMemAddress.new(addr)
|
180
|
+
asm.with_retry do
|
181
|
+
asm.push(tcontext.ret_reg)
|
182
|
+
asm.call(thread_exit)
|
183
|
+
# never reach here
|
184
|
+
end
|
185
|
+
|
186
|
+
# Compile to call ytl_thread_create
|
187
|
+
addr = lambda {
|
188
|
+
a = address_of('ytl_thread_create')
|
189
|
+
$symbol_table[a] = 'yth_thread_create'
|
190
|
+
a
|
191
|
+
}
|
192
|
+
thread_create = OpVarMemAddress.new(addr)
|
193
|
+
|
194
|
+
addr = lambda {
|
195
|
+
a = address_of('ytl_ivar_set_boxing')
|
196
|
+
$symbol_table[a] = 'yth_ivar_set_boxing'
|
197
|
+
a
|
198
|
+
}
|
199
|
+
ivar_set = OpVarMemAddress.new(addr)
|
200
|
+
ivaroff = @modified_instance_var.keys.index(:@_prev_self)
|
201
|
+
orgslf = OpIndirect.new(SPR, AsmType::MACHINE_WORD.size)
|
202
|
+
|
203
|
+
asm = context.assembler
|
204
|
+
context.start_using_reg(TMPR2)
|
205
|
+
asm.with_retry do
|
206
|
+
asm.mov(TMPR, @frame_info.offset_arg(2, BPR))
|
207
|
+
asm.push(TMPR)
|
208
|
+
end
|
209
|
+
context.ret_reg = TMPR
|
210
|
+
context = cursig[2].gen_copy(context)
|
211
|
+
|
212
|
+
asm.with_retry do
|
213
|
+
asm.push(context.ret_reg)
|
214
|
+
|
215
|
+
# write prev self to copyed self
|
216
|
+
asm.mov(TMPR2, orgslf)
|
217
|
+
asm.mov(FUNC_ARG[0], context.ret_reg)
|
218
|
+
asm.mov(FUNC_ARG[1], ivaroff)
|
219
|
+
asm.mov(FUNC_ARG[2], TMPR2)
|
220
|
+
asm.call_with_arg(ivar_set, 3)
|
221
|
+
|
222
|
+
asm.mov(TMPR, @frame_info.offset_arg(1, BPR))
|
223
|
+
asm.push(TMPR) # block addr
|
224
|
+
asm.push(BPR) # oldbp
|
225
|
+
asm.push(THEPR)
|
226
|
+
asm.mov(TMPR, SPR)
|
227
|
+
asm.mov(FUNC_ARG[0], TMPR)
|
228
|
+
asm.mov(TMPR, @block_cs.var_base_immidiate_address)
|
229
|
+
asm.mov(FUNC_ARG[1], TMPR)
|
230
|
+
end
|
231
|
+
context = gen_call(context, thread_create, 2)
|
232
|
+
asm.with_retry do
|
233
|
+
asm.add(SPR, AsmType::MACHINE_WORD.size * 5)
|
234
|
+
end
|
235
|
+
|
236
|
+
context.end_using_reg(TMPR2)
|
237
|
+
context.ret_reg = RETR
|
238
|
+
context.ret_node = self
|
239
|
+
|
240
|
+
return context
|
241
|
+
else
|
242
|
+
super
|
243
|
+
end
|
244
|
+
else
|
245
|
+
super
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
data/runtime/prelude.rb
CHANGED
@@ -55,6 +55,10 @@ class Array
|
|
55
55
|
def at(idx)
|
56
56
|
self[idx]
|
57
57
|
end
|
58
|
+
|
59
|
+
def first
|
60
|
+
self[0]
|
61
|
+
end
|
58
62
|
end
|
59
63
|
|
60
64
|
class Range
|
@@ -76,18 +80,48 @@ class Range
|
|
76
80
|
self
|
77
81
|
end
|
78
82
|
|
83
|
+
def collect
|
84
|
+
res = []
|
85
|
+
rp = 0
|
86
|
+
=begin
|
87
|
+
self.each do |n|
|
88
|
+
res[rp] = yield n
|
89
|
+
rp = rp + 1
|
90
|
+
end
|
91
|
+
=end
|
92
|
+
#=begin
|
93
|
+
i = self.first
|
94
|
+
e = self.last
|
95
|
+
if self.exclude_end? then
|
96
|
+
while i < e
|
97
|
+
res[rp] = yield i
|
98
|
+
rp = rp + 1
|
99
|
+
i = i + 1
|
100
|
+
end
|
101
|
+
else
|
102
|
+
while i <= e
|
103
|
+
res[rp] = yield i
|
104
|
+
rp = rp + 1
|
105
|
+
i = i + 1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
#=end
|
109
|
+
|
110
|
+
res
|
111
|
+
end
|
112
|
+
|
79
113
|
def to_a
|
80
114
|
i = self.first
|
81
115
|
e = self.last
|
82
116
|
res = []
|
83
117
|
if self.exclude_end? then
|
84
118
|
while i < e
|
85
|
-
res
|
119
|
+
res << i
|
86
120
|
i = i + 1
|
87
121
|
end
|
88
122
|
else
|
89
123
|
while i <= e
|
90
|
-
res
|
124
|
+
res << i
|
91
125
|
i = i + 1
|
92
126
|
end
|
93
127
|
end
|
@@ -107,6 +141,26 @@ class Fixnum
|
|
107
141
|
self
|
108
142
|
end
|
109
143
|
|
144
|
+
def upto(n)
|
145
|
+
i = self
|
146
|
+
while i <= n
|
147
|
+
yield i
|
148
|
+
i = i + 1
|
149
|
+
end
|
150
|
+
|
151
|
+
self
|
152
|
+
end
|
153
|
+
|
154
|
+
def downto(n)
|
155
|
+
i = self
|
156
|
+
while i >= n
|
157
|
+
yield i
|
158
|
+
i = i - 1
|
159
|
+
end
|
160
|
+
|
161
|
+
self
|
162
|
+
end
|
163
|
+
|
110
164
|
def step(max, st)
|
111
165
|
i = self
|
112
166
|
if st > 0 then
|
@@ -134,5 +188,14 @@ class Fixnum
|
|
134
188
|
end
|
135
189
|
end
|
136
190
|
|
191
|
+
class IO
|
192
|
+
def each_line
|
193
|
+
while str = gets
|
194
|
+
yield str
|
195
|
+
end
|
196
|
+
nil
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
137
200
|
EOS
|
138
201
|
|
data/runtime/thread.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ytl/thread.rb'
|
2
|
+
include YTLJit
|
3
|
+
include InternalRubyType
|
4
|
+
|
5
|
+
tr_context.import_object(YTLJit::Runtime, :Thread, Runtime::Thread)
|
6
|
+
<<-'EOS'
|
7
|
+
#
|
8
|
+
|
9
|
+
def self_merge(cself, pself)
|
10
|
+
cself
|
11
|
+
end
|
12
|
+
|
13
|
+
module YTLJit
|
14
|
+
module Runtime
|
15
|
+
class Thread
|
16
|
+
def join
|
17
|
+
_join
|
18
|
+
caller = self_of_caller
|
19
|
+
newself = caller.self_merge(self.cself, self.pself)
|
20
|
+
_merge(newself)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
EOS
|
27
|
+
|
data/runtime/type.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
include YTLJit
|
2
2
|
include InternalRubyType
|
3
3
|
|
4
|
+
tr_context.import_object(YTLJit, :AsmType, YTLJit::AsmType)
|
5
|
+
tr_context.import_object(YTLJit, :Runtime, YTLJit::Runtime)
|
4
6
|
tr_context.import_object(YTLJit::AsmType, :VALUE, VALUE)
|
5
7
|
tr_context.import_object(YTLJit::AsmType, :P_CHAR, P_CHAR)
|
6
8
|
tr_context.import_object(YTLJit::AsmType, :RBasic, RBasic)
|
data/test/bar.rb
ADDED