Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

support for Ruby 1.9.3 buggy

  • Loading branch information...
commit 42c6a163ef0e702ab7552c1d7b95649aa3c3ce6f 2 parents fef581f + 7919e50
@miura1729 authored
View
4 lib/instruction.rb 100644 → 100755
@@ -6,8 +6,8 @@
module VMLib
class InstSeqTree
Headers = %w(magic major_version minor_version format_type
- misc name filename type locals args exception_table)
-# misc name filename line type locals args exception_table)
+ misc name filename filepath line typhe locals args exception_table)
+# misc name filename type locals args exception_table)
# call-seq:
# VMLib::InstSeqTree.new(parent, iseq)
# parent Partent of InstSeqTree
View
28 lib/intruby.rb 100644 → 100755
@@ -17,6 +17,20 @@ module LLVM::RubyInternals
VALUE # u3
])
P_RNODE = Type.pointer(RNODE)
+ METHOD_DEFINITION = Type::struct([LONG, # type
+ VALUE, # original_id
+ VALUE, # cfunc
+ LONG # alias_count
+ ])
+ P_METHOD_DEFINITION = Type.pointer(METHOD_DEFINITION)
+
+ METHOD_ENTRY = Type::struct([LONG, # flag
+ P_METHOD_DEFINITION, # def
+ VALUE, # called_id
+ VALUE # klass
+ ])
+ P_METHOD_ENTRY = Type.pointer(METHOD_ENTRY)
+
end
module YARV2LLVM
@@ -68,14 +82,14 @@ def gen_get_method_cfunc_common(builder, issing)
klass = b.call(sing_class, klass)
end
- ftype = Type.function(P_RNODE, [VALUE, VALUE, VALUE])
- rmn = builder.external_function('rb_get_method_body', ftype)
- pnode = b.call(rmn, klass, id, 0.llvm)
+ ftype = Type.function(P_METHOD_ENTRY, [VALUE, VALUE])
+# rmn = builder.external_function('rb_get_method_entry', ftype)
+ rmn = builder.external_function('rb_method_entry_get_without_cache', ftype)
+ pme = b.call(rmn, klass, id)
- vpcnode = b.struct_gep(pnode, 3)
- vcnode =b.load(vpcnode)
- pcnode = b.int_to_ptr(vcnode, P_RNODE)
- pcfunc = b.struct_gep(pcnode, 2)
+ vpmdef = b.struct_gep(pme, 1)
+ vmdef =b.load(vpmdef)
+ pcfunc = b.struct_gep(vmdef, 2)
cfunc = b.load(pcfunc)
b.store(cfunc, cachep)
b.return(cfunc)
View
89 lib/llvmutil.rb 100644 → 100755
@@ -41,6 +41,15 @@ def implicit_type_conversion(b, context, val, type)
val
end
+ def implicit_type_conversion2(b, context, val, srctype, dsttype)
+ if dsttype.type.llvm == Type::DoubleTy and
+ srctype.type.llvm == Type::Int32Ty then
+
+ val = b.si_to_fp(val, Type::DoubleTy)
+ end
+ val
+ end
+
def convert_type_for_2arg_op(b, context, p1, p2)
RubyType.resolve
nop = lambda {|val, type| [val, type]}
@@ -239,13 +248,13 @@ def gen_loop_proc(para)
if rec[0].type.is_a?(ComplexType) then
rec[0].type.element_type.add_same_type atype
# atype.add_same_type rec[0].type.element_type
- else
+ elsif rec[0].type then
rec[0].add_same_type atype
- atype.add_same_type rec[0]
end
end
lambda {|b, context, lst, led, body, recval, excl|
+=begin
if argsize == 1 then
if rec[0].type.is_a?(ComplexType) then
rec[0].type.element_type.add_same_type atype
@@ -256,6 +265,7 @@ def gen_loop_proc(para)
end
end
RubyType.resolve
+=end
bcond = context.builder.create_block
bbody = context.builder.create_block
@@ -411,6 +421,7 @@ def gen_method_select(rectype, lexklass, mname)
# Search lexcal class
obj = Object.nested_const_get(lexklass)
end
+
if obj then
obj.ancestors.each do |sup|
minfo = mtab[sup.name.to_sym]
@@ -421,11 +432,13 @@ def gen_method_select(rectype, lexklass, mname)
end
candidatenum = mtab.size
+ candidate = []
if candidatenum > 1 then
candidatenum = 0
mtab.each {|klass, info|
if info[:func] then
candidatenum += 1
+ candidate.push info
end
}
end
@@ -454,6 +467,10 @@ def gen_method_select(rectype, lexklass, mname)
elsif candidatenum < MaxSmallPolymotphicNum then
# TODO : Use inline hash function generation
+ p rectype.conflicted_types.keys
+ p rectype.inspect2
+ p rectype.name
+ p lexklass
raise("Not implimented polymorphic methed call yet '#{mname}' #{lexklass}")
else
@@ -470,7 +487,7 @@ def get_inline_function(recklass, lexklass, mname)
obj = Object.nested_const_get(lexklass)
end
- if obj then
+ if obj and obj != NilClass then
obj.ancestors.each do |sup|
kls = sup.name.to_sym
if tbl = MethodDefinition::InlineMethod[kls] and
@@ -645,8 +662,8 @@ def gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
nargs = ins[2]
args.each_with_index do |pe, n|
if minfo then
- pe[0].add_same_type(minfo[:argtype][nargs - n - 1])
- minfo[:argtype][nargs - n - 1].add_same_value(pe[0])
+# pe[0].add_same_type(minfo[:argtype][nargs - n - 1])
+# minfo[:argtype][nargs - n - 1].add_same_value(pe[0])
pe[0].add_extent_base minfo[:argtype][nargs - n - 1]
end
para[n] = pe
@@ -661,7 +678,7 @@ def gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
end
if minfo and minfo[:self] then
v[0].add_same_type minfo[:self]
- minfo[:self].add_same_type v[0]
+# minfo[:self].add_same_type v[0]
end
else
v = [local_vars[2][:type],
@@ -670,6 +687,27 @@ def gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
context}]
end
+=begin
+ unless minfo
+ old_tiat = @type_inferece_after_traverse
+ @type_inferece_after_traverse = lambda {
+ old_tiat.call
+ unless minfo
+ minfo, func = gen_method_select(receiver[0], info[0], mname)
+ if minfo and minfo[:self] then
+ args.each_with_index do |pe, n|
+ pe[0].add_same_type(minfo[:argtype][nargs - n - 1])
+ minfo[:argtype][nargs - n - 1].add_same_value(pe[0])
+ pe[0].add_extent_base minfo[:argtype][nargs - n - 1]
+ end
+ v[0].add_same_type minfo[:self]
+ minfo[:self].add_same_type v[0]
+ end
+ end
+ }
+ end
+=end
+
para.push [local_vars[2][:type], lambda {|b, context|
context = v[1].call(b, context)
if v[0].type then
@@ -723,6 +761,32 @@ def gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
yrett = minfoy[:yield_rettype]
brett.add_same_type yrett
yrett.add_same_type brett
+ else
+ old_tiat2 = @type_inferece_after_traverse
+ @type_inferece_after_traverse = lambda {
+ old_tiat2.call
+ recklass = receiver[0].klass
+ minfoy = MethodDefinition::RubyMethod[mname][recklass]
+ minfob = MethodDefinition::RubyMethod[blab][info[0]]
+
+ if minfoy and minfob then
+ yargt = minfoy[:yield_argtype]
+ bargt = minfob[:argtype]
+ if yargt and bargt then
+ yargt.each_with_index do |pe, n|
+# pe.add_same_type bargt[n]
+# bargt[n].add_same_type pe
+ end
+ end
+
+ brett = minfob[:rettype]
+ yrett = minfoy[:yield_rettype]
+ if brett and yrett then
+ brett.add_same_type yrett
+ yrett.add_same_type brett
+ end
+ end
+ }
end
para.push [local_vars[1][:type],
@@ -736,6 +800,7 @@ def gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
end
# receiver of block is parent class
minfo = MethodDefinition::RubyMethod[blab][info[0]]
+
gen_get_block_ptr(info[0], minfo, b, context)
}]
end
@@ -764,6 +829,18 @@ def do_function(receiver, info, ins, local_vars, args, mname, curlevel)
pppp "RubyMethod called #{mname.inspect}"
para = gen_arg_eval(args, receiver, ins, local_vars, info, minfo, mname)
+
+ nargt = minfo[:argtype]
+ nargt.each_with_index do |ele, n|
+ para[n][0].add_same_type ele
+# ele.add_same_type para[n][0]
+ end
+
+ if minfo[:rettype] then
+ rettype.add_same_type minfo[:rettype]
+ minfo[:rettype].add_same_type rettype
+ end
+
if func == nil then
level = @expstack.size
if @array_alloca_size == nil or @array_alloca_size < 1 + level then
View
25 lib/methoddef.rb 100644 → 100755
@@ -90,9 +90,15 @@ module MethodDefinition
idx = para[:args][1]
arr = para[:receiver]
RubyType.resolve
- if arr[0].type.is_a?(ArrayType) then
- val[0].add_same_type(arr[0].type.element_type)
- arr[0].type.element_type.add_same_type(val[0])
+ if arr[0].type.is_a?(ArrayType) then
+ val[0].add_same_type arr[0].type.element_type
+ arr[0].type.element_type.add_same_type val[0]
+ elsif arr[0].type == nil then
+ act = AbstructContainerType.new(nil)
+ arr[0].type = act
+
+ val[0].add_same_type act.element_type
+ act.element_type.add_same_type val[0]
end
val[0].add_extent_base arr[0]
@@ -103,9 +109,9 @@ module MethodDefinition
case arr[0].type
when ArrayType
- val[0].add_same_type(arr[0].type.element_type)
- arr[0].type.element_type.add_same_type(val[0])
- RubyType.resolve
+# val[0].add_same_type(arr[0].type.element_type)
+# arr[0].type.element_type.add_same_type(val[0])
+# RubyType.resolve
ftype = Type.function(Type::VoidTy,
[VALUE, MACHINE_WORD, VALUE])
func = context.builder.external_function('rb_ary_store', ftype)
@@ -255,7 +261,7 @@ module MethodDefinition
when Type::Int32Ty
context.rc = b.sub(0.llvm, val)
else
- raise "Unsupported type #{val[0].inspect2} in -@"
+ raise "Unsupported type #{recv[0].inspect2} in -@"
end
context}]
},
@@ -520,6 +526,7 @@ module MethodDefinition
context
else
+ p rec[0].conflicted_types.keys
raise "Do not supported #{rec[0].inspect2}"
end
}]
@@ -566,13 +573,13 @@ module MethodDefinition
if minfo[:argtype][i] == nil then
minfo[:argtype][i] = RubyType.new(nil)
end
- minfo[:argtype][i].add_same_type ele[0]
+# minfo[:argtype][i].add_same_type ele[0]
ele[0].add_same_type minfo[:argtype][i]
ele[0].add_extent_base minfo[:argtype][i]
ele[0].slf = rettype
end
# minfo[:argtype][-1].add_same_type rec[0]
- rec[0].add_same_type minfo[:argtype][-1]
+# rec[0].add_same_type minfo[:argtype][-1]
#=end
@expstack.push [rettype,
View
20 lib/type.rb 100644 → 100755
@@ -97,9 +97,11 @@ def content
return @type.content
end
@same_value.reverse.each do |ty|
- cont = ty.type.content
- if !UNDEF.equal?(cont) then
- return cont
+ if ty.type then
+ cont = ty.type.content
+ if !UNDEF.equal?(cont) then
+ return cont
+ end
end
end
UNDEF
@@ -346,7 +348,6 @@ def real_extent
if extmax.extent == :instance then
slf = extmax.slf
if slf.is_arg then
- p "foo"
return :global
else
return slf.real_extent
@@ -459,10 +460,9 @@ def self.from_sym(sym, lno, name)
else
obj = nil
if sym then
- obj = sym.to_s.split(/::/).inject(Object) {|res, sym|
- res.const_get(sym.to_sym, true)
- }
+ obj = Object.nested_const_get(sym)
end
+
unless obj
obj = Object
end
@@ -741,7 +741,7 @@ class AbstructContainerType<ComplexType
include RubyHelpers
def initialize(etype)
- set_klass(Object)
+ set_klass(AbstructContainer)
@element_type = RubyType.new(etype)
@content = UNDEF
@constant = UNDEF
@@ -818,7 +818,7 @@ def has_cycle?
def inspect2
if @element_type then
if has_cycle? then
- "Array of VALUE"
+ "Array of Array of ..."
else
"Array of #{@element_type.inspect2}"
end
@@ -885,7 +885,7 @@ def has_cycle?
def inspect2
if @element_type then
if has_cycle? then
- "Hash of VALUE"
+ "Hash of Hash of ..."
else
"Hash of #{@element_type.inspect2}"
end
View
229 lib/vmtraverse.rb 100644 → 100755
@@ -246,12 +246,26 @@ def initialize(iseq, bind, preload)
@global_var_tab = Hash.new {|gltab, glname|
gltab[glname] = {}
}
+
+ # Hook for type infererence. This is called in between ending of traverse
+ # all yarv code and 2nd pass for code generation.
+ @type_inferece_after_traverse = lambda {}
end
include IntRuby
def run
super
+ if OPTION[:var_signature] then
+ @global_var_tab.each do |vn, vtab|
+ if tinfo = vtab[:type] then
+ print "#{vn} : #{tinfo.inspect2} \n"
+ else
+ print "#{vn} : nil \n"
+ end
+ end
+ end
+
# generate code for access Ruby internal
if OPTION[:cache_instance_variable] then
if @instance_var_tab.size != 0 then
@@ -326,7 +340,7 @@ def compile_for_macro(str, lmac, para)
}
end
- is = RubyVM::InstructionSequence.compile(str, "macro", 0,
+ is = RubyVM::InstructionSequence.compile(str, "macro", "", 0,
{ :peephole_optimization => true,
:inline_const_cache => false,
:specialized_instruction => true,}).to_a
@@ -596,9 +610,11 @@ def visit_block_start(code, ins, local_vars, ln, info)
lvars = context.local_vars
1.upto(numarg) do |n|
- dsttype = lvars[-n][:type]
+ dsttype = lvars[-n][:area_type]
+ srctype = lvars[-n][:type]
+# dsttype = lvars[-n][:type]
srcval = arg[n - 1]
- srcval = implicit_type_conversion(b, context, srcval, dsttype)
+ srcval = implicit_type_conversion2(b, context, srcval, srctype, dsttype)
b.store(srcval, lvars[-n][:area])
end
@@ -692,6 +708,14 @@ def visit_block_end(code, ins, local_vars, ln, info)
orggen_deffunc = @generated_define_func[info[0]][info[1]]
@generated_define_func[info[0]][info[1]] = lambda {|iargs|
inlineargs = iargs
+ RubyType.resolve
+ @type_inferece_after_traverse.call
+ RubyType.resolve
+ @type_inferece_after_traverse.call
+ RubyType.resolve
+ @type_inferece_after_traverse.call
+ RubyType.resolve
+ @type_inferece_after_traverse = lambda {}
if OPTION[:func_signature] then
# write function prototype
print "#{info[0]}##{info[1]} :("
@@ -917,6 +941,7 @@ def visit_local_block_start(code, ins, local_vars, ln, info)
if labels.size > 0 then
rc = b.phi(phitype.type.llvm)
labels.reverse.each do |lab|
+# p context.block_value[lab][1]
rc.add_incoming(context.block_value[lab][1],
context.blocks_tail[lab])
end
@@ -948,8 +973,8 @@ def visit_local_block_end(code, ins, local_vars, ln, info)
# don't call before visit_block_start call.
if @is_live == nil then
@is_live = true
+ @prev_label = ln
end
- @prev_label = ln
# p @expstack.map {|n| n[1]}
end
@@ -1224,6 +1249,7 @@ def visit_getglobal(code, ins, local_vars, ln, info)
type.extent = :global
end
areap = @global_var_tab[glname][:area]
+
@expstack.push [type,
lambda {|b, context|
ftype = Type.function(VALUE, [VALUE])
@@ -1262,14 +1288,16 @@ def visit_setglobal(code, ins, local_vars, ln, info)
srcvalue = src[1]
srctype.add_same_value(dsttype)
- dsttype.add_same_value(srctype)
+ dsttype.add_same_type(srctype)
srctype.extent = :global
+ dsttype.extent = :global
oldrescode = @rescode
@rescode = lambda {|b, context|
context = oldrescode.call(b, context)
context = srcvalue.call(b, context)
srcval = context.rc
+ srcval = implicit_type_conversion(b, context, srcval, srctype)
srcval2 = srctype.type.to_value(srcval, b, context)
dsttype.type = dsttype.type.dup_type
@@ -1900,11 +1928,37 @@ def visit_send(code, ins, local_vars, ln, info)
end
end
+ minfo = nil
+ func = nil
rett = RubyType.new(nil, info[3], "Return forward type of #{mname}")
+
+ old_tiat = @type_inferece_after_traverse
+ @type_inferece_after_traverse = lambda {
+ old_tiat.call
+ rectype = receiver ? receiver[0] : nil
+ minfo, func = gen_method_select(rectype, info[0], mname)
+ if minfo == nil then
+ # Retry for generate dynamic dispatch.
+ minfo, func = gen_method_select(rectype, nil, mname)
+ end
+
+ if minfo then
+ nargt = minfo[:argtype]
+ nargt.each_with_index do |ele, n|
+ para[n][0].add_same_type ele
+ ele.add_same_type para[n][0]
+ end
+ rett.add_same_type minfo[:rettype]
+ minfo[:rettype].add_same_type rett
+ end
+ }
+
@expstack.push [rett,
lambda {|b, context|
+
recklass = receiver ? receiver[0].klass : nil
rectype = receiver ? receiver[0] : nil
+
minfo, func = gen_method_select(rectype, info[0], mname)
if minfo == nil then
# Retry for generate dynamic dispatch.
@@ -1912,15 +1966,6 @@ def visit_send(code, ins, local_vars, ln, info)
end
if func then
- nargt = minfo[:argtype]
- nargt.each_with_index do |ele, n|
- para[n][0].add_same_type ele
- ele.add_same_type para[n][0]
- end
- rett.add_same_type minfo[:rettype]
- minfo[:rettype].add_same_type rett
- RubyType.resolve
-
if !with_selfp(receiver, info[0], mname) then
para.pop
end
@@ -1946,7 +1991,28 @@ def visit_send(code, ins, local_vars, ln, info)
return
end
- # invokesuper
+ def visit_invokesuper(code, ins, local_vars, ln, info)
+ if info[0] then
+ nargs = ins[1]
+ args = []
+ 0.upto(nargs - 1) do |n|
+ args.push @expstack.pop
+ end
+ @expstack.pop
+ @expstack.push nil
+ args.each do |e|
+ @expstack.push e
+ end
+
+ klass = Object.const_get(info[0], true)
+ supklass = klass.superclass
+ nins = [:send, info[1], ins[1], ins[2], ins[3]]
+ ninfo = [supklass.to_s.to_sym, info[1], info[2], info[3], info[4]]
+ visit_send(code, nins, local_vars, ln, ninfo)
+ else
+ raise "Toplevel of super?"
+ end
+ end
def visit_invokeblock(code, ins, local_vars, ln, info)
# @have_yield = true
@@ -2019,6 +2085,7 @@ def visit_leave(code, ins, local_vars, ln, info)
rett2 = nil
if code.lblock_list.last != ln then
@is_live = false
+ @prev_label = ln
end
if retexp == nil then
@@ -2046,6 +2113,7 @@ def visit_leave(code, ins, local_vars, ln, info)
if rett2.type == nil then
retexp[0].add_same_type rett2
RubyType.resolve
+# retexp[0].resolve
if rett2.type == nil then
rett2.type = PrimitiveType.new(VALUE, nil)
@@ -2120,6 +2188,7 @@ def visit_jump(code, ins, local_vars, ln, info)
end
bval = nil
@is_live = false
+ @prev_label = ln
@jump_from[lab] ||= []
@jump_from[lab].push ln
@rescode = lambda {|b, context|
@@ -2176,6 +2245,7 @@ def visit_branchif(code, ins, local_vars, ln, info)
bval = [valexp[0], valexp[1].call(b, context).rc]
context.block_value[iflab] = bval
end
+
condval = cond[1].call(b, context).rc
if cond[0].type.llvm != Type::Int1Ty then
vcond = cond[0].type.to_value(condval, b, context)
@@ -2650,7 +2720,7 @@ def visit_opt_neq(code, ins, local_vars, ln, info)
context.rc = b.icmp_ne(sval[0], sval[1])
else
- context = gen_call_from_ruby(stype[0], rett, :==, [s1, s2], 0,
+ context = gen_call_from_ruby(stype[0], rett, :!=, [s1, s2], 0,
b, context)
ret = context.rc
context.rc = b.icmp_eq(ret, true.llvm)
@@ -2813,7 +2883,14 @@ def visit_opt_ltlt(code, ins, local_vars, ln, info)
if s1[0].type
if s1[0].type.klass == :String then
rettype = check_same_type_2arg_static(s1, s2)
- elsif s1[0].type.klass != :Array then
+ elsif s1[0].type.klass == :Array then
+ rettype = RubyType.array(info[3], "Return type of ltlt")
+ s1[0].add_same_type rettype
+ rettype.add_same_type s1[0]
+ s2[0].add_same_type rettype.type.element_type
+ rettype.type.element_type.add_same_type s2[0]
+ RubyType.resolve
+ else
rettype = check_same_type_2arg_static(s1, s2)
end
end
@@ -2861,7 +2938,26 @@ def opt_aref_aux(b, context, arr, idx, rettype, level, info, indx)
when :Array
context = idx[1].call(b, context)
idxp = context.rc
- if OPTION[:array_range_check] then
+ if idx[0].klass == :Range then
+ context = arr[1].call(b, context)
+ arrp = context.rc
+
+ idxptr = context.array_alloca_area
+ b.store(idxp, idxptr)
+
+ ftype = Type.function(VALUE, [LONG, P_VALUE, VALUE])
+ func = context.builder.external_function('rb_ary_aref', ftype)
+ av = b.call(func, 1.llvm, idxptr, arrp)
+ arrelet = arr[0].type.element_type.type
+ if arrelet then
+ context.rc = arrelet.from_value(av, b, context)
+ else
+ context.rc = av
+ end
+ context
+
+
+ elsif OPTION[:array_range_check] then
context = arr[1].call(b, context)
arrp = context.rc
ftype = Type.function(VALUE, [VALUE, MACHINE_WORD])
@@ -3002,18 +3098,11 @@ def opt_aref_aux(b, context, arr, idx, rettype, level, info, indx)
def visit_opt_aref(code, ins, local_vars, ln, info)
idx = @expstack.pop
arr = @expstack.pop
- case arr[0].klass
- when :Array
- fix = RubyType.fixnum(info[3])
- idx[0].add_same_type(fix)
- fix.add_same_value(idx[0])
- end
RubyType.resolve
# AbstrubctContainorType is type which have [] and []= as method.
if arr[0].type == nil then
- # RubyType.new(AbstructContainerType.new(nil)).add_same_type arr[0]
arr[0].type = AbstructContainerType.new(nil)
end
@@ -3021,7 +3110,19 @@ def visit_opt_aref(code, ins, local_vars, ln, info)
indx = nil
case arr[0].klass
when :Array #, :Object
- rettype = arr[0].type.element_type
+ if idx[0].klass == :Range then
+ rettype = arr[0].dup_type
+ level = @expstack.size
+ if @array_alloca_size == nil or @array_alloca_size < 1 + level then
+ @array_alloca_size = 1 + level
+ end
+ else
+ fix = RubyType.fixnum(info[3])
+ idx[0].add_same_type(fix)
+ fix.add_same_value(idx[0])
+
+ rettype = arr[0].type.element_type
+ end
when :Struct, :Hash
rettype = RubyType.value
@@ -3040,14 +3141,26 @@ def visit_opt_aref(code, ins, local_vars, ln, info)
rettype.type.type = arr[0].type.type.member[indx]
end
- when :Object
- rettype = arr[0].type.element_type
+ when :Object, :AbstructContainer
+ if idx[0].klass == :Range then
+ rettype = arr[0].dup_type
+ level = @expstack.size
+ if @array_alloca_size == nil or @array_alloca_size < 1 + level then
+ @array_alloca_size = 1 + level
+ end
+ elsif idx[0].klass == :Fixnum then
+ rettype = arr[0].type.element_type
+ else
+ rettype = arr[0].type.element_type
+ end
- else
+ when :NilClass
rettype = RubyType.new(nil)
- # p info
- # pp arr[0]
- # raise "Unkown Type #{arr[0].klass}"
+
+ else
+ p info
+ pp arr[0]
+ raise "Unkown Type #{arr[0].klass}"
end
@expstack.push [rettype,
@@ -3092,6 +3205,38 @@ def visit_opt_length(code, ins, local_vars, ln, info)
}]
end
+ def visit_opt_size(code, ins, local_vars, ln, info)
+ rec = @expstack.pop
+ level = @expstack.size
+ if @array_alloca_size == nil or @array_alloca_size < 1 + level then
+ @array_alloca_size = 1 + level
+ end
+
+ rettype = RubyType.fixnum(info[3], "return type of length", Fixnum)
+ @expstack.push [rettype,
+ lambda {|b, context|
+ case rec[0].type.klass
+ when :String
+ context = rec[1].call(b, context)
+ recval = context.rc
+ recval = rec[0].type.to_value(recval, b, context)
+ ftype = Type.function(VALUE, [VALUE])
+ func = context.builder.external_function('rb_str_length', ftype)
+ rcvalue = b.call(func, recval)
+ context.rc = rettype.type.from_value(rcvalue, b, context)
+
+ when :Array
+ context = gen_call_from_ruby(rettype, rec[0], :length, [rec], level,
+ b, context)
+
+ else
+ raise "Not support type #{rec[0].inspect2} in length"
+ end
+
+ context
+ }]
+ end
+
# opt_succ
def visit_opt_not(code, ins, local_vars, ln, info)
@@ -3106,6 +3251,10 @@ def visit_opt_not(code, ins, local_vars, ln, info)
bool = b.and(recval, (~4).llvm)
context.rc = b.icmp_eq(bool, 0.llvm)
+ if rettype.klass == :Object then
+ rc = context.rc
+ context.rc = RubyType.boolean.type.to_value(rc, b, context)
+ end
context
}]
@@ -3149,6 +3298,10 @@ def store_to_local(voff, src, local_vars, ln, info)
srctype.add_extent_base dsttype
srctype.add_same_type(areatype)
+ dsttype.resolve
+ srctype.resolve
+# RubyType.resolve
+
=begin
RubyType.resolve
if dsttype.dst_type and
@@ -3223,6 +3376,10 @@ def store_to_parent(voff, slev, src, acode, ln, info)
srctype.add_extent_base dsttype
srctype.add_same_type(areatype)
+ dsttype.resolve
+ srctype.resolve
+# RubyType.resolve
+
=begin
RubyType.resolve
if dsttype.dst_type and
@@ -3335,7 +3492,7 @@ def set_have_yield(info, val)
end
def compile_file(fn, opt = {}, preload = [], bind = TOPLEVEL_BINDING)
- is = RubyVM::InstructionSequence.compile( File.read(fn), fn, 1,
+ is = RubyVM::InstructionSequence.compile( File.read(fn), fn, "", 1,
{ :peephole_optimization => true,
:inline_const_cache => false,
:specialized_instruction => true,}).to_a
@@ -3350,7 +3507,7 @@ def compile(str, opt = {}, preload = [], bind = TOPLEVEL_BINDING)
line = $2.to_i + 1
method = $3
end
- is = RubyVM::InstructionSequence.compile( str, file, line,
+ is = RubyVM::InstructionSequence.compile( str, file, "", line,
{ :peephole_optimization => true,
:inline_const_cache => false,
:specialized_instruction => true,}).to_a
@@ -3366,12 +3523,12 @@ def compcommon(is, opt, preload, bind)
end
iseq = VMLib::InstSeqTree.new(nil, is)
if OPTION[:dump_yarv] then
- p iseq.to_a
+ pp iseq.to_a
end
prelude = 'runtime/prelude.rb'
pcont = File.read(prelude)
pconty2l = eval(pcont)
- preis = RubyVM::InstructionSequence.compile(pconty2l, prelude, 1,
+ preis = RubyVM::InstructionSequence.compile(pconty2l, prelude, "", 1,
{ :peephole_optimization => true,
:inline_const_cache => false,
:specialized_instruction => true,}).to_a
View
4 lib/yarv2llvm.rb
@@ -34,6 +34,7 @@ module YARV2LLVM
:dump_yarv => false,
:write_bc => false,
:func_signature => false,
+ :var_signature => false,
:array_range_check => true,
@@ -110,6 +111,9 @@ def llvm
end
end
+class AbstructContainer
+end
+
module LLVM::RubyInternals
RFLOAT = Type.struct([RBASIC, Type::DoubleTy])
P_RFLOAT = Type.pointer(RFLOAT)
View
2  lib/yarv2ruby.rb 100644 → 100755
@@ -92,7 +92,7 @@ def visit_block_end(code, ins, local_vars, ln, info)
def visit_local_block_start(code, ins, local_vars, ln, info)
if ln then
- @curlln = (@curlabel.to_s + ln).to_sym
+ @curlln = (@curlabel.to_s + ln.to_s).to_sym
@labels[@curlabel].push @curlln
oldcode = @generated_code[@curlln]
@generated_code[@curlln] = lambda {|context|
View
67 runtime/prelude.rb 100644 → 100755
@@ -1,5 +1,4 @@
module YARV2LLVM
-#=begin
# type definition of method
@@ -57,7 +56,7 @@ module YARV2LLVM
:rettype => rt,
:copy_rettype => true,
}
-#=begin
+
MethodDefinition::RubyMethod[:at][:Array] = {
:self => nil,
:argtype => [RubyType.new(nil)],
@@ -70,7 +69,7 @@ module YARV2LLVM
rt
},
}
-#=end
+
st = RubyType.array
rt = RubyType.new(nil)
rt.add_same_type(st.type.element_type)
@@ -98,6 +97,40 @@ module YARV2LLVM
rt = RubyType.array
rt.add_same_type(st)
st.add_same_type(rt)
+ MethodDefinition::RubyMethod[:sort][:AbstructContainer] = {
+ :self => st,
+ :argtype => [],
+ :rettype => rt,
+ :copy_rettype => true,
+ }
+
+ st = RubyType.array
+ rt = RubyType.array
+ rt.add_same_type(st)
+ st.add_same_type(rt)
+ MethodDefinition::RubyMethod[:sort!][:AbstructContainer] = {
+ :self => st,
+ :argtype => [],
+ :rettype => rt,
+ :copy_rettype => true,
+ }
+
+
+ st = RubyType.array
+ rt = RubyType.array
+ rt.add_same_type(st)
+ st.add_same_type(rt)
+ MethodDefinition::RubyMethod[:uniq!][:AbstructContainer] = {
+ :self => st,
+ :argtype => [],
+ :rettype => rt,
+ :copy_rettype => true,
+ }
+
+ st = RubyType.array
+ rt = RubyType.array
+ rt.add_same_type(st)
+ st.add_same_type(rt)
MethodDefinition::RubyMethod[:slice!][:Array] = {
:self => st,
:argtype => [RubyType.new(nil), RubyType.new(nil)],
@@ -151,12 +184,12 @@ module YARV2LLVM
:rettype => lst,
:copy_rettype => true,
}
-#=end
+
end
<<-'EOS'
#
-
+#=begin
YARV2LLVM::define_macro :attr_reader do |arg|
arg.each do |argele|
name = argele[0].type.constant
@@ -225,10 +258,11 @@ def **(n)
class Array
def collect
- res = []
+ res = Array.new
i = 0
- self.each do |e|
- res[i] = yield e
+ max = self.size
+ while i < max
+ res[i] = yield self[i]
i = i + 1
end
@@ -254,15 +288,24 @@ def step(st)
end
def collect
- res = []
+ res = Array.new
i = 0
- self.each do |e|
- res[i] = yield e
- i = i + 1
+ max = self.last
+ if self.exclude_end? then
+ while i < max do
+ res[i] = yield i
+ i = i + 1
+ end
+ else
+ while i <= max do
+ res[i] = yield i
+ i = i + 1
+ end
end
res
end
end
+#=end
EOS
View
9 sample/hello.rb 100644 → 100755
@@ -1,14 +1,17 @@
m = LLVM::Module.new('hello')
LLVM::ExecutionEngine.get(m)
-p_char = LLVM::pointer(Type::Int8Ty)
-ftype = LLVM::function(Type::Int32Ty, [p_char])
+p_char = Type.pointer(Type::Int8Ty)
+#ftype = LLVM::function(Type::Int32Ty, [p_char])
+ftype = Type.function(Type::Int32Ty, [p_char])
ftype = ftype.to_raw
printf = m.external_function('printf', ftype)
-ftype = LLVM::function(Type::Int32Ty, [])
+#ftype = LLVM::function(Type::Int32Ty, [])
+ftype = Type.function(Type::Int32Ty, [])
ftype = ftype.to_raw
main = m.get_or_insert_function('main', ftype)
b = main.create_block.builder
strptr = b.create_global_string_ptr("Hello World! \n")
b.call(printf, strptr)
b.return(strptr)
+#b.return(LLVM::Value.get_constant(Type::Int32Ty, 0))
LLVM::ExecutionEngine.run_function(main)
View
7 test/test_unsafe.rb
@@ -7,7 +7,7 @@
class UnsafeTests < Test::Unit::TestCase
def test_unsafe
- YARV2LLVM::compile(<<-EOS, {:disasm => true, :dump_yarv => true, :optimize=> true})
+ YARV2LLVM::compile(<<-EOS, {:disasm => false, :dump_yarv => false, :optimize=> true})
def tunsafe
type = LLVM::struct([RubyHelpers::VALUE, LLVM::Type::Int32Ty, RubyHelpers::VALUE, RubyHelpers::VALUE])
a = [:a, :b]
@@ -28,7 +28,7 @@ def tunsafe2
end
def test_define_external_function
- YARV2LLVM::compile(<<-EOS, {:disasm => true, :dump_yarv => true, :optimize=> true, :func_signature => true})
+ YARV2LLVM::compile(<<-EOS, {:disasm => false, :dump_yarv => false, :optimize=> true, :func_signature => true})
def tdefine_external_function
value = RubyHelpers::VALUE
int32ty = LLVM::Type::Int32Ty
@@ -45,7 +45,7 @@ def tdefine_external_function
end
def test_define_macro
- YARV2LLVM::compile(<<-'EOS', {:disasm => true, :dump_yarv => true, :optimize=> false, :func_signature => false})
+ YARV2LLVM::compile(<<-'EOS', {:disasm => false, :dump_yarv => false, :optimize=> false, :func_signature => false})
YARV2LLVM::define_macro :myif do |arg| `if #{_sender_env[:args][2]} then #{_sender_env[:args][1]} else #{_sender_env[:args][0]} end` end
@@ -57,5 +57,4 @@ def tdefine_macro
EOS
assert_equal(tdefine_macro, "hello")
end
-
end
View
3  y2llib/llvmruby.rb 100644 → 100755
@@ -14,7 +14,8 @@ module YARV2LLVM
}
MethodDefinition::RubyMethod[:builder][:"LLVM::BasicBlock"] = {
- :argtype => [RubyType.value, RubyType.array],
+# :argtype => [RubyType.value, RubyType.array],
+ :argtype => [],
:rettype => RubyType.value(nil, "Return type of Type::function", :Builder),
}
View
7 yarv2llvm.rb 100644 → 100755
@@ -26,7 +26,7 @@
'Execute FILE by Ruby1.9 before compile main program') do |f|
rf = File.read(f)
prog = eval(rf)
- is = RubyVM::InstructionSequence.compile( prog, f, 1,
+ is = RubyVM::InstructionSequence.compile( prog, f, "", 1,
{ :peephole_optimization => true,
:inline_const_cache => false,
:specialized_instruction => true,}).to_a
@@ -78,6 +78,11 @@
y2lopt[:func_signature] = f
end
+ opt.on('--[no-]var-signature',
+ 'Display type inferenced inforamtion about global variable') do |f|
+ y2lopt[:var_signature] = f
+ end
+
opt.on('--[no-]type-message',
'Display type message for example Type Conflict Error') do |f|
y2lopt[:type_message] = f
Please sign in to comment.
Something went wrong with that request. Please try again.