samples/dynamic_ruby.rb in metasm-1.0.2 vs samples/dynamic_ruby.rb in metasm-1.0.3
- old
+ new
@@ -450,12 +450,12 @@
local(args[3][1], C::CExpression[v])
end
end
# compile a case/when
- # create a real C switch() for Fixnums, and put the others === in the default case
- # XXX will get the wrong order for "case x; when 1; when Fixnum; when 3;" ...
+ # create a real C switch() for Integers, and put the others === in the default case
+ # XXX will get the wrong order for "case x; when 1; when Integer; when 3;" ...
def compile_case(ast, scope, want_value)
# this generates
# var = stuff_to_test()
# if (var & 1)
# switch (var >> 1) {
@@ -470,11 +470,11 @@
# if (var == true.object_id || rb_test(rb_funcall(bla, '===', var)))
# foo();
# else {
# default();
# }
- #
+ #
if want_value == true
ret = get_new_tmp_var('case', want_value)
want_value = ret
elsif want_value
ret = want_value
@@ -496,11 +496,11 @@
ast[2..-1].each { |cs|
if cs[0] == :when
raise Fail if cs[1][0] != :array
# numeric case, add a case to body_int
- if cs[1][1..-1].all? { |cd| cd[0] == :lit and (cd[1].kind_of? Fixnum or cd[1].kind_of? Range) }
+ if cs[1][1..-1].all? { |cd| cd[0] == :lit and (cd[1].kind_of? Integer or cd[1].kind_of? Range) }
cs[1][1..-1].each { |cd|
if cd[1].kind_of? Range
b = cd[1].begin
e = cd[1].end
e -= 1 if cd[1].exclude_end?
@@ -518,11 +518,11 @@
# non-numeric (or mixed) case, add if ( cs === var )
else
cnd = nil
cs[1][1..-1].each { |cd|
- if (cd[0] == :lit and (cd[1].kind_of?(Fixnum) or cd[1].kind_of?(Symbol))) or
+ if (cd[0] == :lit and (cd[1].kind_of?(Integer) or cd[1].kind_of?(Symbol))) or
[:nil, :true, :false].include?(cd[0])
# true C equality
cd = C::CExpression[var, :==, ast_to_c(cd, scope)]
else
# own block for ast_to_c to honor lazy evaluation
@@ -539,11 +539,11 @@
cnd = (cnd ? C::CExpression[cnd, :'||', cd] : cd)
}
cb = C::Block.new(scope)
v = ast_to_c(cs[2], cb, want_value)
cb.statements << C::CExpression[ret, :'=', v] if want_value and v != ret
-
+
fu = C::If.new(cnd, cb, nil)
if body_other
body_other.belse = fu
else
@@ -657,11 +657,11 @@
def rb_cast_pvalue(expr, idx)
C::CExpression[[[expr], C::Pointer.new(value)], :'[]', [idx]]
end
# retrieve the current class, from self->klass
- # XXX will segfault with self.kind_of? Fixnum/true/false/nil/sym
+ # XXX will segfault with self.kind_of? Integer/true/false/nil/sym
def rb_selfclass
rb_cast_pvalue(rb_self, 1)
end
def rb_nil
@@ -808,11 +808,11 @@
# returns the C::CExpr holding the VALUE of the current ruby statement
# want_value is an optionnal hint as to the returned VALUE is needed or not
# if want_value is a C::Variable, the statements should try to populate this var instead of some random tmp var
# eg to simplify :if encoding unless we have 'foo = if 42;..'
def ast_to_c(ast, scope, want_value = true)
- ret =
+ ret =
case ast.to_a[0]
when :block
if ast[1]
ast[1..-2].each { |a| ast_to_c(a, scope, false) }
ast_to_c(ast.last, scope, want_value)
@@ -1083,17 +1083,17 @@
rb_const(ast[1], ::Object)
when :defined
case ast[1][0]
when :ivar
fcall('rb_ivar_defined', rb_self, rb_intern(ast[1][1]))
- else
+ else
raise Fail, "unsupported #{ast.inspect}"
end
when :masgn
# parallel assignment: put everything in an Array, then pop everything back?
rb_masgn(ast, scope, want_value)
-
+
when :evstr
fcall('rb_obj_as_string', ast_to_c(ast[1], scope))
when :dot2, :dot3
fcall('rb_range_new', ast_to_c(ast[1], scope), ast_to_c(ast[2], scope), ast[0] == :dot2 ? 0 : 1)
when :splat
@@ -1136,19 +1136,19 @@
op = ast[2]
int = C::BaseType.new(:ptr) # signed VALUE
args = ast[3][1..-1] if ast[3] and ast[3][0] == :array
arg0 = args[0] if args and args[0]
- if arg0 and arg0[0] == :lit and arg0[1].kind_of?(Fixnum) and %w[== > < >= <= + -].include?(op)
+ if arg0 and arg0[0] == :lit and arg0[1].kind_of?(Integer) and %w[== > < >= <= + -].include?(op)
# TODO or @optim_hint[ast[1]] == 'fixnum'
# optimize 'x==42', 'x+42', 'x-42'
o2 = arg0[1]
if o2 < 0 and ['+', '-'].include? op
# need o2 >= 0 for overflow detection
op = {'+' => '-', '-' => '+'}[op]
o2 = -o2
- return if not o2.kind_of? Fixnum # -0x40000000
+ return if not o2.kind_of? Integer # -0x40000000
end
int_v = o2.object_id
recv = ast_to_c(ast[1], scope)
tmp = get_new_tmp_var('opt', want_value)
@@ -1157,15 +1157,15 @@
recv = tmp
end
case op
when '=='
- # XXX assume == only return true for full equality: if not Fixnum, then always false
+ # XXX assume == only return true for full equality: if not Integer, then always false
# which breaks 1.0 == 1 and maybe others, but its ok
scope.statements << C::If.new(ce[recv, :'==', [int_v]], ce[tmp, :'=', rb_true], ce[tmp, :'=', rb_false])
when '>', '<', '>=', '<='
- # do the actual comparison on signed >>1 if both Fixnum
+ # do the actual comparison on signed >>1 if both Integer
t = C::If.new(
ce[[[[recv], int], :>>, [1]], op.to_sym, [[[int_v], int], :>>, [1]]],
ce[tmp, :'=', rb_true],
ce[tmp, :'=', rb_false])
# fallback to actual rb_funcall
@@ -1192,11 +1192,11 @@
else
scope.statements << C::If.new(cnd, t, e)
end
end
tmp
-
+
# Symbol#==
elsif arg0 and arg0[0] == :lit and arg0[1].kind_of? Symbol and op == '=='
s_v = ast_to_c(arg0, scope)
tmp = get_new_tmp_var('opt', want_value)
recv = ast_to_c(ast[1], scope, tmp)
@@ -1242,17 +1242,17 @@
end
idx = ce[[idx], int]
ar = C::Block.new(scope)
ar.statements << ce[idx, :'=', [[[arg], int], :>>, [1]]]
- ar.statements << C::If.new(ce[idx, :<, [0]], ce[idx, :'=', [idx, :+, rb_ary_len(recv)]], nil)
+ ar.statements << C::If.new(ce[idx, :<, [0]], ce[idx, :'=', [idx, :+, rb_ary_len(recv)]], nil)
ar.statements << C::If.new(ce[[idx, :<, [0]], :'||', [idx, :>=, [[rb_ary_len(recv)], int]]],
ce[tmp, :'=', rb_nil],
ce[tmp, :'=', rb_ary_ptr(recv, idx)])
st = C::Block.new(scope)
st.statements << ce[idx, :'=', [[[arg], int], :>>, [1]]]
- st.statements << C::If.new(ce[idx, :<, [0]], ce[idx, :'=', [idx, :+, rb_str_len(recv)]], nil)
+ st.statements << C::If.new(ce[idx, :<, [0]], ce[idx, :'=', [idx, :+, rb_str_len(recv)]], nil)
st.statements << C::If.new(ce[[idx, :<, [0]], :'||', [idx, :>=, [[rb_str_len(recv)], int]]],
ce[tmp, :'=', rb_nil],
ce[tmp, :'=', [[[[rb_str_ptr(recv, idx), :&, [0xff]], :<<, [1]], :|, [1]], value]])
hsh = ce[tmp, :'=', fcall('rb_hash_aref', recv, arg)]
oth = ce[tmp, :'=', rb_funcall(recv, op, arg)]
@@ -1302,12 +1302,11 @@
test =
case arg0[1]
when 'Symbol'
tmp = get_new_tmp_var('kindof', want_value)
ce[[ast_to_c(ast[1], scope, tmp), :'&', [0xf]], :'==', [0xe]]
- #when 'Numeric', 'Integer'
- when 'Fixnum'
+ when 'Integer'
tmp = get_new_tmp_var('kindof', want_value)
ce[ast_to_c(ast[1], scope, tmp), :'&', [0x1]]
when 'Array'
rb_test_class_ary(ast_to_c(ast[1], scope))
when 'String'
@@ -1501,11 +1500,11 @@
# int.times { |i| }
elsif b_recv[0] == :call and not b_recv[3] and b_recv[2] == 'times'
limit = get_new_tmp_var('limit')
recv = ast_to_c(b_recv[1], scope, limit)
- scope.statements << C::If.new(C::CExpression[:'!', [recv, :&, 1]], rb_raise('only Fixnum#times handled'), nil)
+ scope.statements << C::If.new(C::CExpression[:'!', [recv, :&, 1]], rb_raise('only Integer#times handled'), nil)
if want_value
scope.statements << C::CExpression[@iter_break, :'=', recv]
end
scope.statements << C::CExpression[limit, :'=', [recv, :>>, 1]]
cntr = get_new_tmp_var('cntr')
@@ -1551,11 +1550,11 @@
body = C::Block.new(scope)
if b_args and b_args[0] == :dasgn_curr
body.statements << C::CExpression[dvar(b_args[1]), :'=', [rb_ary_ptr(ary), :'[]', [cntr]]]
end
# same as #each up to this point (except default retval), now add a 'if (body_value) break ary[cntr];'
- # XXX 'find { next true }'
+ # XXX 'find { next true }'
found = ast_to_c(b_body, body)
t = C::Block.new(body)
t.statements << C::CExpression[@iter_break, :'=', rb_ary_ptr(ary, cntr)]
t.statements << C::Break.new
@@ -1578,11 +1577,11 @@
body = C::Block.new(scope)
if b_args and b_args[0] == :dasgn_curr
body.statements << C::CExpression[dvar(b_args[1]), :'=', [rb_ary_ptr(ary), :'[]', [cntr]]]
end
# same as #each up to this point (except default retval), now add a '@iter_break << body_value'
- # XXX 'next' unhandled
+ # XXX 'next' unhandled
val = ast_to_c(b_body, body)
body.statements << fcall('rb_ary_push', @iter_break, val)
scope.statements << C::For.new(C::CExpression[cntr, :'=', [[0], cntr.type]], C::CExpression[cntr, :<, rb_ary_len(ary)], C::CExpression[:'++', cntr], body)
@@ -1640,11 +1639,11 @@
static void do_init_once(void) {
// const_Lol = rb_const_get(*rb_cObject, rb_intern("Lol"));
// rb_define_method(const_Lol, "method", method, 2);
}
-int Init_compiledruby(void) __attribute__((export)) {
+int Init_compiledruby(void) __attribute__((export)) {
// use a separate func to avoid having to append statements before the 'return'
do_init_once();
return 0;
}
EOS
@@ -1662,11 +1661,11 @@
return if not mname
@compiled_func_cache[[klass, method.to_s, singleton]] = @cur_cfunc
cls = rb_const(nil, klass)
-
+
init.statements << fcall("rb_define#{'_singleton' if singleton}_method", cls, method.to_s, @cur_cfunc, method_arity)
mname
end
@@ -1697,10 +1696,10 @@
def rb_intern(sym)
n = escape_varname("intern_#{sym}")
@cp.toplevel.symbol[n] || declare_newtopvar(n, fcall('rb_intern', sym.to_s), C::BaseType.new(:int, :unsigned))
end
- # rb_const 'FOO', Bar::Baz ==>
+ # rb_const 'FOO', Bar::Baz ==>
# const_Bar = rb_const_get(rb_cObject, rb_intern("Bar"));
# const_Bar_Baz = rb_const_get(const_Bar, rb_intern("Baz"));
# const_Bar_Baz_FOO = rb_const_get(const_Bar_Baz, rb_intern("FOO"));
# use rb_const(nil, class) to get a pointer to a class/module
def rb_const(constname, owner = resolve_const_owner(constname))