ytl 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +37 -0
- data/bin/ytl +11 -0
- data/lib/ytl/accmem.rb +334 -0
- data/lib/ytl/importobj.rb +10 -0
- data/lib/ytl.rb +131 -0
- data/runtime/prelude.rb +30 -0
- data/runtime/type.rb +10 -0
- data/test/basictest.rb +146 -0
- data/test/classtest.rb +50 -0
- data/test/exceptiontest.rb +21 -0
- data/test/exttest.rb +35 -0
- data/test/floattest.rb +4 -0
- data/test/looptest.rb +20 -0
- data/test/tmp.rb +7 -0
- metadata +97 -0
data/README
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
1. Waht is ytl
|
2
|
+
|
3
|
+
Ytl is translator from CRuby VM (aka YARV) to X86-32/X86-64 Native Code.
|
4
|
+
Ytl uses ytljit as code generate library.
|
5
|
+
|
6
|
+
2. Install
|
7
|
+
|
8
|
+
Install ytljit
|
9
|
+
gem install ytljit
|
10
|
+
|
11
|
+
Enjoy or take pains
|
12
|
+
|
13
|
+
3. Sample
|
14
|
+
|
15
|
+
ruby lib/ytl.rb test/basictest.rb
|
16
|
+
|
17
|
+
"copy" # This message is for debug
|
18
|
+
"copy" # This message is for debug
|
19
|
+
"copy" # This message is for debug
|
20
|
+
"copy" # This message is for debug
|
21
|
+
1
|
22
|
+
1.9
|
23
|
+
3
|
24
|
+
14930352
|
25
|
+
4
|
26
|
+
14
|
27
|
+
|
28
|
+
3. License
|
29
|
+
|
30
|
+
Ruby's
|
31
|
+
|
32
|
+
4. Author
|
33
|
+
|
34
|
+
Miura Hideki
|
35
|
+
m-72 at tf6.so-net.ne.jp (e-mail)
|
36
|
+
http://twitter.com/miura1729 (twitter)
|
37
|
+
http://d.hatena.ne.jp/miura1729 (blog in japanese)
|
data/bin/ytl
ADDED
data/lib/ytl/accmem.rb
ADDED
@@ -0,0 +1,334 @@
|
|
1
|
+
module YTL
|
2
|
+
class Memory
|
3
|
+
end
|
4
|
+
TheMemory = Memory.new
|
5
|
+
end
|
6
|
+
|
7
|
+
module YTLJit
|
8
|
+
module VM
|
9
|
+
module Node
|
10
|
+
|
11
|
+
class SendElementRefMemoryNode<SendElementRefNode
|
12
|
+
include SendUtil
|
13
|
+
include X86
|
14
|
+
include X64
|
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
|
+
def collect_candidate_type_regident(context, slf)
|
35
|
+
if slf.ruby_type <= YTL::Memory then
|
36
|
+
kind = @arguments[4]
|
37
|
+
kvalue = kind.get_constant_value
|
38
|
+
|
39
|
+
if kvalue then
|
40
|
+
kvalue =kvalue[0]
|
41
|
+
|
42
|
+
case kvalue
|
43
|
+
when :char, :word, :dword, :machine_word
|
44
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
45
|
+
add_type(context.to_signature, fixtype)
|
46
|
+
|
47
|
+
when :float
|
48
|
+
floattype = RubyType::BaseType.from_ruby_class(Float)
|
49
|
+
add_type(context.to_signature, floattype)
|
50
|
+
|
51
|
+
when AsmType::StructMember
|
52
|
+
if kvalue.type.is_a?(AsmType::Scalar) then
|
53
|
+
if kvalue.type.kind == :int then
|
54
|
+
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
55
|
+
add_type(context.to_signature, ttype)
|
56
|
+
else
|
57
|
+
raise "Unkown type #{kvalue.type} #{kvalue.type.kind}"
|
58
|
+
end
|
59
|
+
else
|
60
|
+
raise "Unkown type #{kvalue}"
|
61
|
+
end
|
62
|
+
|
63
|
+
when AsmType::Scalar
|
64
|
+
if kvalue.kind == :int then
|
65
|
+
ttype = RubyType::BaseType.from_ruby_class(Fixnum)
|
66
|
+
add_type(context.to_signature, ttype)
|
67
|
+
|
68
|
+
else
|
69
|
+
raise "Unkown type"
|
70
|
+
end
|
71
|
+
|
72
|
+
else
|
73
|
+
raise "Unkown type #{kvalue}"
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
else
|
78
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
79
|
+
add_type(context.to_signature, fixtype)
|
80
|
+
end
|
81
|
+
|
82
|
+
context
|
83
|
+
|
84
|
+
elsif slf.ruby_type <= AsmType::Pointer or
|
85
|
+
slf.ruby_type <= AsmType::Array then
|
86
|
+
tt = AsmType::PointedData
|
87
|
+
pointedtype = RubyType::BaseType.from_ruby_class(tt)
|
88
|
+
add_type(context.to_signature, pointedtype)
|
89
|
+
context
|
90
|
+
|
91
|
+
elsif slf.ruby_type <= AsmType::Struct or
|
92
|
+
slf.ruby_type <= AsmType::Union or
|
93
|
+
slf.ruby_type <= AsmType::StructMember then
|
94
|
+
tt = AsmType::StructMember
|
95
|
+
stmemtype = RubyType::BaseType.from_ruby_class(tt)
|
96
|
+
add_type(context.to_signature, stmemtype)
|
97
|
+
context
|
98
|
+
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def compile_ref_scalar(context, typeobj)
|
105
|
+
context
|
106
|
+
end
|
107
|
+
|
108
|
+
def gen_read_mem(context, size)
|
109
|
+
asm = context.assembler
|
110
|
+
case size
|
111
|
+
when 8
|
112
|
+
asm.with_retry do
|
113
|
+
if context.ret_reg != RAX then
|
114
|
+
asm.mov(RAX, context.ret_reg)
|
115
|
+
end
|
116
|
+
asm.mov(RAX, INDIRECT_RAX)
|
117
|
+
end
|
118
|
+
context.ret_reg = RAX
|
119
|
+
|
120
|
+
when 4
|
121
|
+
asm.with_retry do
|
122
|
+
if context.ret_reg != EAX then
|
123
|
+
asm.mov(EAX, context.ret_reg)
|
124
|
+
end
|
125
|
+
asm.mov(EAX, INDIRECT_EAX)
|
126
|
+
end
|
127
|
+
context.ret_reg = EAX
|
128
|
+
|
129
|
+
when 2
|
130
|
+
asm.with_retry do
|
131
|
+
asm.mov(AL, context.ret_reg)
|
132
|
+
asm.mov(AL, INDIRECT_AL)
|
133
|
+
end
|
134
|
+
context.ret_reg = EAX
|
135
|
+
|
136
|
+
else
|
137
|
+
raise "Unkown Scalar size #{kvalue}"
|
138
|
+
end
|
139
|
+
|
140
|
+
context
|
141
|
+
end
|
142
|
+
|
143
|
+
def compile(context)
|
144
|
+
slf = @arguments[2]
|
145
|
+
slf.decide_type_once(context.to_signature)
|
146
|
+
if slf.type.ruby_type <= YTL::Memory then
|
147
|
+
asm = context.assembler
|
148
|
+
|
149
|
+
kind = @arguments[4]
|
150
|
+
kvalue = nil
|
151
|
+
case kind
|
152
|
+
when LiteralNode
|
153
|
+
kvalue = kind.value
|
154
|
+
|
155
|
+
else
|
156
|
+
context = kind.compile(context)
|
157
|
+
if context.ret_reg.is_a?(OpVarImmidiateAddress) then
|
158
|
+
objid = (context.ret_reg.value >> 1)
|
159
|
+
kvalue = ObjectSpace._id2ref(objid)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
context = @arguments[3].compile(context)
|
164
|
+
|
165
|
+
case kvalue
|
166
|
+
when :machine_word
|
167
|
+
asm.with_retry do
|
168
|
+
if context.ret_reg != TMPR then
|
169
|
+
asm.mov(TMPR, context.ret_reg)
|
170
|
+
end
|
171
|
+
asm.mov(RETR, INDIRECT_TMPR)
|
172
|
+
end
|
173
|
+
context.ret_reg = RETR
|
174
|
+
|
175
|
+
when :float
|
176
|
+
asm.with_retry do
|
177
|
+
if context.ret_reg != TMPR then
|
178
|
+
asm.mov(TMPR, context.ret_reg)
|
179
|
+
end
|
180
|
+
asm.mov(RETFR, INDIRECT_TMPR)
|
181
|
+
end
|
182
|
+
context.ret_reg = RETFR
|
183
|
+
|
184
|
+
when AsmType::Scalar
|
185
|
+
context = gen_read_mem(context, kvalue.size)
|
186
|
+
|
187
|
+
when AsmType::StructMember
|
188
|
+
typeobj = kvalue.type
|
189
|
+
case typeobj
|
190
|
+
when AsmType::Scalar
|
191
|
+
context = gen_read_mem(context, typeobj.size)
|
192
|
+
|
193
|
+
else
|
194
|
+
raise "Unkown Struct Member type #{kvalue}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context.ret_node = self
|
199
|
+
return context
|
200
|
+
|
201
|
+
elsif slf.type.ruby_type <= AsmType::TypeCommon then
|
202
|
+
context = @arguments[2].compile(context)
|
203
|
+
obj = slf.get_constant_value
|
204
|
+
|
205
|
+
if obj == nil and
|
206
|
+
context.ret_reg.is_a?(OpVarImmidiateAddress) then
|
207
|
+
objid = (context.ret_reg.value >> 1)
|
208
|
+
obj = ObjectSpace._id2ref(objid)
|
209
|
+
else
|
210
|
+
obj = obj[0]
|
211
|
+
end
|
212
|
+
|
213
|
+
if obj then
|
214
|
+
index = @arguments[3].get_constant_value
|
215
|
+
|
216
|
+
if index then
|
217
|
+
index = index[0]
|
218
|
+
val = obj[index]
|
219
|
+
add = lambda { val.address }
|
220
|
+
context.ret_reg = OpVarImmidiateAddress.new(add)
|
221
|
+
context.ret_node = self
|
222
|
+
|
223
|
+
return context
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
super
|
228
|
+
else
|
229
|
+
super
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
class SendNewArenaNode<SendNewNode
|
235
|
+
add_special_send_node :new
|
236
|
+
|
237
|
+
def traverse_childlen
|
238
|
+
@arguments.each do |arg|
|
239
|
+
yield arg
|
240
|
+
end
|
241
|
+
yield @func
|
242
|
+
yield @body
|
243
|
+
end
|
244
|
+
|
245
|
+
def collect_candidate_type_regident(context, slf)
|
246
|
+
if Runtime::Arena.is_a?(slf.ruby_type) then
|
247
|
+
slfcls = @arguments[2].get_constant_value
|
248
|
+
tt = RubyType::BaseType.from_ruby_class(slfcls[0])
|
249
|
+
add_type(context.to_signature, tt)
|
250
|
+
|
251
|
+
if @initmethod.is_a?(SendInitializeNode) then
|
252
|
+
# Get alloc method call node
|
253
|
+
@initmethod = @initmethod.arguments[2]
|
254
|
+
end
|
255
|
+
|
256
|
+
return context
|
257
|
+
end
|
258
|
+
|
259
|
+
return super
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class SendAddressNode<SendNode
|
264
|
+
include InternalRubyType
|
265
|
+
add_special_send_node :address
|
266
|
+
|
267
|
+
def collect_candidate_type_regident(context, slf)
|
268
|
+
if slf.ruby_type == Runtime::Arena then
|
269
|
+
tt = RubyType::BaseType.from_ruby_class(Fixnum)
|
270
|
+
add_type(context.to_signature, tt)
|
271
|
+
|
272
|
+
return context
|
273
|
+
end
|
274
|
+
|
275
|
+
super
|
276
|
+
end
|
277
|
+
|
278
|
+
def compile(context)
|
279
|
+
context = @arguments[2].compile(context)
|
280
|
+
@arguments[2].decide_type_once(context.to_signature)
|
281
|
+
rtype = @arguments[2].type
|
282
|
+
rrtype = rtype.ruby_type
|
283
|
+
if rrtype == Runtime::Arena then
|
284
|
+
asm = context.assembler
|
285
|
+
rsdata = TypedData.new(RData, context.ret_reg)
|
286
|
+
asm.with_retry do
|
287
|
+
dmy, arena = asm.mov(TMPR, rsdata[:data])
|
288
|
+
asm.mov(TMPR, arena[0][:body])
|
289
|
+
end
|
290
|
+
context.ret_reg = TMPR
|
291
|
+
context.ret_node = self
|
292
|
+
context
|
293
|
+
else
|
294
|
+
super
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
class SendInstanceMemoryNode<SendNode
|
300
|
+
add_special_send_node :instance
|
301
|
+
|
302
|
+
def collect_candidate_type_regident(context, slf)
|
303
|
+
if YTL::Memory.is_a?(slf.ruby_type) then
|
304
|
+
slfcls = @arguments[2].get_constant_value
|
305
|
+
if slfcls then
|
306
|
+
tt = RubyType::BaseType.from_ruby_class(slfcls[0])
|
307
|
+
add_type(context.to_signature, tt)
|
308
|
+
end
|
309
|
+
|
310
|
+
return context
|
311
|
+
end
|
312
|
+
|
313
|
+
super
|
314
|
+
end
|
315
|
+
|
316
|
+
def compile(context)
|
317
|
+
@arguments[2].decide_type_once(context.to_signature)
|
318
|
+
rtype = @arguments[2].type
|
319
|
+
rrtype = rtype.ruby_type
|
320
|
+
if YTL::Memory.is_a?(rrtype) then
|
321
|
+
objadd = lambda {
|
322
|
+
YTL::TheMemory.address
|
323
|
+
}
|
324
|
+
context.ret_reg = OpVarImmidiateAddress.new(objadd)
|
325
|
+
context.ret_node = self
|
326
|
+
context
|
327
|
+
else
|
328
|
+
super
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
data/lib/ytl.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'ytljit'
|
2
|
+
require 'ytl/accmem.rb'
|
3
|
+
require 'ytl/importobj.rb'
|
4
|
+
require 'pp'
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
include YTLJit
|
8
|
+
module YTL
|
9
|
+
include YTLJit
|
10
|
+
|
11
|
+
ISEQ_OPTS = {
|
12
|
+
:peephole_optimization => true,
|
13
|
+
:inline_const_cache => false,
|
14
|
+
:specialized_instruction => false,
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.parse_opt(argv)
|
18
|
+
ytlopt = {}
|
19
|
+
prelude = File.join(File.dirname(__FILE__), "..", "runtime", "prelude.rb")
|
20
|
+
ytlopt[:execute_before_compile] = [prelude]
|
21
|
+
opt = OptionParser.new
|
22
|
+
|
23
|
+
opt.on('--disasm', 'Disasemble generated code') do |f|
|
24
|
+
ytlopt[:disasm] = f
|
25
|
+
end
|
26
|
+
|
27
|
+
opt.on('--dump-yarv', 'Dump YARV byte code') do |f|
|
28
|
+
ytlopt[:dump_yarv] = f
|
29
|
+
end
|
30
|
+
|
31
|
+
opt.on('--disp-signature', 'Display signature of method') do |f|
|
32
|
+
ytlopt[:disp_signature] = f
|
33
|
+
end
|
34
|
+
|
35
|
+
opt.on('--dump-context', 'Dump context(registor/stack) for debug') do |f|
|
36
|
+
ytlopt[:dump_context] = f
|
37
|
+
end
|
38
|
+
|
39
|
+
opt.on('--write-code =FILE', 'Write generating code') do |f|
|
40
|
+
ytlopt[:write_code] = f
|
41
|
+
end
|
42
|
+
|
43
|
+
opt.on('--write-node-before-type-inference =FILE',
|
44
|
+
'Write node of before type inference') do |f|
|
45
|
+
ytlopt[:write_node_before_ti] = f
|
46
|
+
end
|
47
|
+
|
48
|
+
opt.on('--write-node-after-type-inference =FILE',
|
49
|
+
'Write node of after type inference') do |f|
|
50
|
+
ytlopt[:write_node_after_ti] = f
|
51
|
+
end
|
52
|
+
|
53
|
+
opt.on('-r FILE', '--execute-before-compile =FILE',
|
54
|
+
'Execute ruby program (execute by CRuby)') do |f|
|
55
|
+
ytlopt[:execute_before_compile].push f
|
56
|
+
end
|
57
|
+
|
58
|
+
opt.parse!(argv)
|
59
|
+
ytlopt
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.main(options)
|
63
|
+
tr_context = VM::YARVContext.new
|
64
|
+
progs = []
|
65
|
+
|
66
|
+
import_ruby_object(tr_context)
|
67
|
+
options[:execute_before_compile].each do |fn|
|
68
|
+
rf = File.read(fn)
|
69
|
+
prog = eval(rf)
|
70
|
+
progs.push prog
|
71
|
+
end
|
72
|
+
|
73
|
+
prog = progs.join("\n") + File.read(ARGV[0])
|
74
|
+
is = RubyVM::InstructionSequence.compile(prog, ARGV[0],
|
75
|
+
"", 0, ISEQ_OPTS).to_a
|
76
|
+
iseq = VMLib::InstSeqTree.new(nil, is)
|
77
|
+
if options[:dump_yarv] then
|
78
|
+
pp iseq
|
79
|
+
end
|
80
|
+
|
81
|
+
tr = VM::YARVTranslatorCRubyObject.new([iseq])
|
82
|
+
tnode = tr.translate(tr_context)
|
83
|
+
ci_context = VM::CollectInfoContext.new(tnode)
|
84
|
+
tnode.collect_info(ci_context)
|
85
|
+
|
86
|
+
if fn = options[:write_node_before_ti] then
|
87
|
+
File.open(fn, "w") do |fp|
|
88
|
+
fp.print Marshal.dump(tnode)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
dmylit = VM::Node::LiteralNode.new(tnode, nil)
|
93
|
+
arg = [dmylit, dmylit, dmylit]
|
94
|
+
sig = []
|
95
|
+
arg.each do |ele|
|
96
|
+
sig.push RubyType::BaseType.from_ruby_class(NilClass)
|
97
|
+
end
|
98
|
+
|
99
|
+
ti_context = VM::TypeInferenceContext.new(tnode)
|
100
|
+
begin
|
101
|
+
tnode.collect_candidate_type(ti_context, arg, sig)
|
102
|
+
end until ti_context.convergent
|
103
|
+
ti_context = tnode.collect_candidate_type(ti_context, arg, sig)
|
104
|
+
|
105
|
+
c_context = VM::CompileContext.new(tnode)
|
106
|
+
c_context.current_method_signature.push sig
|
107
|
+
c_context.options = options
|
108
|
+
c_context = tnode.compile(c_context)
|
109
|
+
|
110
|
+
if fn = options[:write_node_after_ti] then
|
111
|
+
File.open(fn, "w") do |fp|
|
112
|
+
fp.print Marshal.dump(tnode)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
if options[:disasm] then
|
117
|
+
tnode.code_space_tab.each do |cs|
|
118
|
+
cs.fill_disasm_cache
|
119
|
+
end
|
120
|
+
tnode.code_space.disassemble
|
121
|
+
end
|
122
|
+
|
123
|
+
tcs = tnode.code_space
|
124
|
+
STDOUT.flush
|
125
|
+
tcs.call(tcs.base_address)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
if __FILE__ == $0 then
|
130
|
+
YTL::main(YTL::parse_opt(ARGV))
|
131
|
+
end
|
data/runtime/prelude.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# runtime library written in ytl
|
2
|
+
<<-'EOS'
|
3
|
+
#
|
4
|
+
class Array
|
5
|
+
def each
|
6
|
+
i = 0
|
7
|
+
e = self.size
|
8
|
+
while i < e
|
9
|
+
yield self[i]
|
10
|
+
i = i + 1
|
11
|
+
end
|
12
|
+
|
13
|
+
self
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Fixnum
|
18
|
+
def times
|
19
|
+
i = 0
|
20
|
+
while i < self
|
21
|
+
yield i
|
22
|
+
i = i + 1
|
23
|
+
end
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
EOS
|
30
|
+
|
data/runtime/type.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
include YTLJit
|
2
|
+
include InternalRubyType
|
3
|
+
|
4
|
+
tr_context.import_object(YTLJit::AsmType, :VALUE, VALUE)
|
5
|
+
tr_context.import_object(YTLJit::AsmType, :P_CHAR, P_CHAR)
|
6
|
+
tr_context.import_object(YTLJit::AsmType, :RBasic, RBasic)
|
7
|
+
tr_context.import_object(YTLJit::AsmType, :RString, RString)
|
8
|
+
tr_context.import_object(YTLJit::AsmType, :RFloat, RFloat)
|
9
|
+
tr_context.import_object(YTLJit::Runtime, :Arena, Runtime::Arena)
|
10
|
+
""
|
data/test/basictest.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
def id (x)
|
2
|
+
x
|
3
|
+
end
|
4
|
+
|
5
|
+
p id(1)
|
6
|
+
p id(1.9)
|
7
|
+
|
8
|
+
def array
|
9
|
+
a = [3, 5, 6]
|
10
|
+
p a
|
11
|
+
a[1] = 1
|
12
|
+
p a
|
13
|
+
[1, 2, 3][0] + [1, 2, 3][1]
|
14
|
+
end
|
15
|
+
p array
|
16
|
+
|
17
|
+
def fib(x)
|
18
|
+
if x < 2 then
|
19
|
+
1
|
20
|
+
else
|
21
|
+
fib(x-1) + fib(x-2)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
p fib(35)
|
26
|
+
|
27
|
+
def fib2(x)
|
28
|
+
if x < 2 then
|
29
|
+
1.0
|
30
|
+
else
|
31
|
+
fib2(x-1) + fib2(x-2)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
p fib2(35)
|
36
|
+
|
37
|
+
def blk0(x)
|
38
|
+
yield(x) + 2
|
39
|
+
end
|
40
|
+
|
41
|
+
def blk1(x)
|
42
|
+
yield(x) + 10
|
43
|
+
end
|
44
|
+
|
45
|
+
p blk0(1) {|a| a + 1}
|
46
|
+
p blk1(1) {|a| blk0(a) {|b| b + a}}
|
47
|
+
|
48
|
+
def blk3
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
|
52
|
+
p id(blk3 { "abc"})
|
53
|
+
p id(blk3 { 1 })
|
54
|
+
|
55
|
+
def mul(x, y)
|
56
|
+
x * y
|
57
|
+
end
|
58
|
+
|
59
|
+
p mul(30, 40)
|
60
|
+
p mul(30, -40)
|
61
|
+
p mul(-30, 40)
|
62
|
+
p mul(-30, -40)
|
63
|
+
p mul(30.0, 40.0)
|
64
|
+
p mul(30.0, -40.0)
|
65
|
+
p mul(-30.0, 40.0)
|
66
|
+
p mul(-30.0, -40.0)
|
67
|
+
|
68
|
+
def div(x, y)
|
69
|
+
x / y
|
70
|
+
end
|
71
|
+
|
72
|
+
p div(30, 4)
|
73
|
+
p div(30, -4)
|
74
|
+
p div(-30, 4)
|
75
|
+
p div(-30, -4)
|
76
|
+
p div(30.0, 7.0)
|
77
|
+
p div(30.0, -7.0)
|
78
|
+
p div(-30.0, 7.0)
|
79
|
+
p div(-30.0, -7.0)
|
80
|
+
p div(35, 7)
|
81
|
+
p div(35, -7)
|
82
|
+
p div(-35, 7)
|
83
|
+
p div(-35, -7)
|
84
|
+
|
85
|
+
p 1 < 1
|
86
|
+
p 1 > 1
|
87
|
+
p 1 <= 1
|
88
|
+
p 1 >= 1
|
89
|
+
|
90
|
+
p 1 < 2
|
91
|
+
p 1 > 2
|
92
|
+
p 1 <= 2
|
93
|
+
p 1 >= 2
|
94
|
+
|
95
|
+
p 1.0 < 2.0
|
96
|
+
p 1.0 > 2.0
|
97
|
+
p 1.0 <= 2.0
|
98
|
+
p 1.0 >= 2.0
|
99
|
+
|
100
|
+
p 1.0 < 1e-17
|
101
|
+
p 1.0 > 1e-17
|
102
|
+
p 1.0 <= 1e-17
|
103
|
+
p 3.0 > 2.0
|
104
|
+
p :foo
|
105
|
+
p :foo == :foo
|
106
|
+
p :foo == :bar
|
107
|
+
p :foo != :foo
|
108
|
+
p :foo != :bar
|
109
|
+
|
110
|
+
def multi_type_var
|
111
|
+
a = 1
|
112
|
+
p a
|
113
|
+
a = "a"
|
114
|
+
p a
|
115
|
+
a = 1.0
|
116
|
+
p a
|
117
|
+
# p 1.0
|
118
|
+
end
|
119
|
+
|
120
|
+
multi_type_var
|
121
|
+
|
122
|
+
def test_while
|
123
|
+
i = 10
|
124
|
+
j = 0
|
125
|
+
k = 10
|
126
|
+
while i > 0
|
127
|
+
while k > 0
|
128
|
+
j = j + i
|
129
|
+
k = k - 1
|
130
|
+
end
|
131
|
+
i = i - 1
|
132
|
+
k = 10
|
133
|
+
end
|
134
|
+
p j
|
135
|
+
|
136
|
+
i = 10
|
137
|
+
j = 0
|
138
|
+
while i > 0
|
139
|
+
i = i - 1
|
140
|
+
j = j + i
|
141
|
+
end
|
142
|
+
p j
|
143
|
+
end
|
144
|
+
|
145
|
+
test_while
|
146
|
+
|
data/test/classtest.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
class Foo
|
2
|
+
def bar
|
3
|
+
p "Foo#bar"
|
4
|
+
end
|
5
|
+
|
6
|
+
def baz
|
7
|
+
p "Foo#baz"
|
8
|
+
p @a
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@a = 4
|
13
|
+
p "initialize Foo"
|
14
|
+
p self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Bar<Foo
|
19
|
+
def bar
|
20
|
+
p "Bar#bar"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
a = Foo.new
|
25
|
+
p a
|
26
|
+
a.bar
|
27
|
+
a.baz
|
28
|
+
b = Bar.new
|
29
|
+
p b
|
30
|
+
b.bar
|
31
|
+
b.baz
|
32
|
+
|
33
|
+
class Baz
|
34
|
+
def self.alloc
|
35
|
+
p "alloc"
|
36
|
+
end
|
37
|
+
p self
|
38
|
+
end
|
39
|
+
|
40
|
+
p Baz.new
|
41
|
+
p Baz.alloc
|
42
|
+
|
43
|
+
#=end
|
44
|
+
=begin
|
45
|
+
class Asd
|
46
|
+
end
|
47
|
+
|
48
|
+
class <<self
|
49
|
+
end
|
50
|
+
=end
|
data/test/exttest.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# Please Execute
|
2
|
+
# ruby -I lib lib/ytl.rb -r runtime/type.rb test/exttest.rb
|
3
|
+
module YTL
|
4
|
+
class Memory
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module YTLJit
|
9
|
+
module AsmType
|
10
|
+
end
|
11
|
+
|
12
|
+
module Runtime
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def id(x)
|
17
|
+
x
|
18
|
+
end
|
19
|
+
|
20
|
+
c = YTLJit::Runtime::Arena.new
|
21
|
+
a = YTL::Memory.instance
|
22
|
+
# b = 0x1046ce30
|
23
|
+
b = c.address
|
24
|
+
p b
|
25
|
+
p c
|
26
|
+
p YTLJit::AsmType::VALUE
|
27
|
+
p YTLJit::AsmType::RBasic[:klass]
|
28
|
+
p YTLJit::AsmType::RString[:as][:heap][:len]
|
29
|
+
p YTLJit::AsmType::RString[:basic][:flags]
|
30
|
+
p a[b, :machine_word]
|
31
|
+
p a[b, :float]
|
32
|
+
#p a[0x106667b8, YTLJit::AsmType::RString[:as][:heap][:ptr]]
|
33
|
+
p a[b, YTLJit::AsmType::RString[:basic][:flags]]
|
34
|
+
p a[b, YTLJit::AsmType::RString[:as][:heap][:len]]
|
35
|
+
p a[b, :machine_word]
|
data/test/floattest.rb
ADDED
data/test/looptest.rb
ADDED
data/test/tmp.rb
ADDED
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ytl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Hideki Miura
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-10 00:00:00 +09:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: ytljit
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
- 4
|
32
|
+
version: 0.0.4
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description:
|
36
|
+
email:
|
37
|
+
executables:
|
38
|
+
- ytl
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- lib/ytl.rb
|
45
|
+
- lib/ytl/accmem.rb
|
46
|
+
- lib/ytl/importobj.rb
|
47
|
+
- runtime/prelude.rb
|
48
|
+
- runtime/type.rb
|
49
|
+
- test/basictest.rb
|
50
|
+
- test/classtest.rb
|
51
|
+
- test/exceptiontest.rb
|
52
|
+
- test/exttest.rb
|
53
|
+
- test/floattest.rb
|
54
|
+
- test/looptest.rb
|
55
|
+
- test/tmp.rb
|
56
|
+
- bin/ytl
|
57
|
+
- README
|
58
|
+
has_rdoc: true
|
59
|
+
homepage:
|
60
|
+
licenses: []
|
61
|
+
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Very tiny subset of YARV to native code translator
|
90
|
+
test_files:
|
91
|
+
- test/basictest.rb
|
92
|
+
- test/classtest.rb
|
93
|
+
- test/exceptiontest.rb
|
94
|
+
- test/exttest.rb
|
95
|
+
- test/floattest.rb
|
96
|
+
- test/looptest.rb
|
97
|
+
- test/tmp.rb
|