Here's a little toy I messed with today for patching Rubinius's
primitives.rb build-time script to produce JRuby-compatible Java code
instead of C. Given that Evan's new C++-based VM is probably going to
eliminate or drastically change the way primitives work, this probably
won't see any real use...but I think if we could provide all of
Rubinius's primitives, we'd be most of the way to reusing their entire
collection of core class impls.
If, of course, that's something we want to do.
- Charlie
class ShotgunPrimitives
def generate_select(fd, op="prim")
primitives = @@primitives
File.open("RubiniusPrimitives.java", "w") do |f|
primitives.each do |prim_name|
f.puts "public static IRubyObject
cpu_primitive_#{prim_name}(ThreadContext context, IRubyObject self,
IRubyObject[] args, Block block) {"
f.puts send(prim_name)
f.puts "}"
end
f.puts "\npublic static abstract class PrimFunc {"
f.puts " public abstract IRubyObject call(ThreadContext context,
IRubyObject self, IRubyObject[] args, Block bloc);"
f.puts "}"
f.puts "\npublic static final PrimFunc[] funcs = { NULL, "
primitives.each do |prim_name|
f.puts " new PrimFunc() {"
f.puts " public IRubyObject call(ThreadContext context,
IRubyObject self, IRubyObject[] args, Block bloc) {"
f.puts " return #{prim_name}(context, self, args, block);"
f.puts " }"
f.puts " },"
end
f.puts "\npublic static PrimFunc cpu_lookup_primitive(int index) {"
f.puts " return funcs[index];"
f.puts "}"
f.puts "public static Map cpu_populate_prim_names() {"
f.puts " Map tbl = new HashMap();"
primitives.each_with_index do |prim_name,i|
f.puts " tbl.put(#{i + 1}, \"#{prim_name}\");"
f.puts " tbl.put(\"#{prim_name}\", #{i + 1});"
end
f.puts "return tbl;"
f.puts "}"
end
end
def add
<<-CODE
#{check_arity(1)};
IRubyObject arg = args[0];
#{guard(fixnum?('arg'))};
if (#{fixnum?('arg')}) {
return #{to_fixnum('arg')}.op_plus(context, arg);
} else if (#{bignum?('arg')}) {
return #{to_bignum('arg')}.op_plus(context, arg);
} else if (#{float?('arg')}) {
return #{to_float('arg')}.op_plus(context, arg);
} else {
throw new RuntimeException(\"primitive :add failed to find a type
match\");
}
CODE
end
private
def check_arity(n)
"Arity.checkArgumentCount(context.getRuntime(), args, #{n}, #{n})"
end
def guard(expr)
"assert #{expr} : \"'#{expr}' failed\""
end
def fixnum?(value_expr)
"#{value_expr} instanceof RubyFixnum"
end
def to_fixnum(value_expr)
"(RubyFixnum(#{value_expr}))"
end
def bignum?(value_expr)
"#{value_expr} instanceof RubyBignum"
end
def to_bignum(value_expr)
"(RubyBignum(#{value_expr}))"
end
def float?(value_expr)
"#{value_expr} instanceof RubyFloat"
end
def to_float(value_expr)
"(RubyFloat(#{value_expr}))"
end
end
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email