Skip to content

Commit

Permalink
Basic signature support for Compiler2.
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@9393 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information
headius committed Mar 11, 2009
1 parent 7417037 commit ad1b581
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 9 deletions.
118 changes: 109 additions & 9 deletions tool/compiler2.rb
@@ -1,4 +1,5 @@
require 'bitescript'
require File.dirname(__FILE__) + '/signature'

RubyObject = org.jruby.RubyObject
RubyBasicObject = org.jruby.RubyBasicObject
Expand All @@ -7,6 +8,9 @@
IRubyObject = org.jruby.runtime.builtin.IRubyObject
ThreadContext = org.jruby.runtime.ThreadContext
LoadService = org.jruby.runtime.load.LoadService
JClass = java.lang.Class
JavaUtil = org.jruby.javasupport.JavaUtil
JObject = java.lang.Object

JAVA_CLASSNAME = ARGV[0]
RUBY_CLASSNAME = ARGV[1]
Expand All @@ -20,6 +24,20 @@
require RUBY_FILENAME
RUBY_CLASS = eval(RUBY_CLASSNAME)

BiteScript.bytecode_version = BiteScript::JAVA1_5

def first_local(params, instance = true)
i = instance ? 1 : 0
params.each do |param|
if param == Java::long || param == Java::double
i += 2
else
i += 1
end
end
i
end

file = BiteScript::FileBuilder.build("#{JAVA_CLASSNAME}.java.rb") do
public_class JAVA_CLASSNAME, RubyObject do
static_init do
Expand All @@ -41,31 +59,113 @@

for method_name in RUBY_CLASS.public_instance_methods(false) do
method = RUBY_CLASS.instance_method(method_name)
params = (method.arity < 0) ? [IRubyObject[]] : [IRubyObject] * method.arity
public_method method_name, IRubyObject, *params do
signature = RUBY_CLASS.signatures[method_name]

if signature
raise "signatures only supported for exact arities: #{RUBY_CLASS.to_s + '#' + method_name}" if method.arity < 0
params = signature.keys[0]
retval = signature[params]
use_ji = true
else
params = (method.arity < 0) ? [IRubyObject[]] : [IRubyObject] * method.arity
retval = IRubyObject
end

public_method method_name, retval, *params do
aload 0
dup
invokeinterface IRubyObject, "getRuntime", [Ruby]
ruby_index = first_local(params)
dup; astore ruby_index
invokevirtual Ruby, "getCurrentContext", [ThreadContext]
ldc method_name
# TODO: arity-specific call
if method.arity < 0
# restarg or optarg, just pass array through
aload 1
else
# all normal args, box them up
if use_ji
# We have a signature and need to use java integration logic
ldc method.arity
anewarray IRubyObject
i = 1;
index = 1
1.upto(method.arity) do |i|
dup
ldc i - 1
aload i
aload ruby_index
param_type = params[i - 1]
if [boolean, byte, short, char, int].include? param_type
iload index
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, int]
elsif long == param_type
lload index
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, long]
index += 1
elsif float == param_type
fload index
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, float]
elsif double == param_type
dload index
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, double]
index += 1
else
aload i
invokestatic JavaUtil, "convertJavaToUsableRubyObject", [IRubyObject, Ruby, object]
end
aastore
index += 1
end
else
if method.arity < 0
# restarg or optarg, just pass array through
aload 1
else
# all normal args, box them up
ldc method.arity
anewarray IRubyObject
i = 1;
1.upto(method.arity) do |i|
dup
ldc i - 1
aload i
aastore
end
end
end
invokevirtual RubyBasicObject, "callMethod", [IRubyObject, ThreadContext, string, IRubyObject[]]
areturn
if use_ji
if boolean == retval
invokestatic JavaUtil, "convertRubyToJavaBoolean", [boolean, IRubyObject]
ireturn
elsif byte == retval
invokestatic JavaUtil, "convertRubyToJavaByte", [byte, IRubyObject]
ireturn
elsif short == retval
invokestatic JavaUtil, "convertRubyToJavaShort", [short, IRubyObject]
ireturn
elsif char == retval
invokestatic JavaUtil, "convertRubyToJavaChar", [char, IRubyObject]
ireturn
elsif int == retval
invokestatic JavaUtil, "convertRubyToJavaInt", [int, IRubyObject]
ireturn
elsif long == retval
invokestatic JavaUtil, "convertRubyToJavaLong", [long, IRubyObject]
lreturn
elsif float == retval
invokestatic JavaUtil, "convertRubyToJavaFloat", [float, IRubyObject]
freturn
elsif double == retval
invokestatic JavaUtil, "convertRubyToJavaDouble", [double, IRubyObject]
dreturn
elsif retval == void
pop
returnvoid
else
ldc retval
invokestatic JavaUtil, "convertRubyToJava", [JObject, IRubyObject, JClass]
areturn
end
else
areturn
end
end
end
end
Expand Down
10 changes: 10 additions & 0 deletions tool/signature.rb
@@ -0,0 +1,10 @@
class Class
def signature(name, signature)
name = name.to_s
signatures[name] = signature
end

def signatures
@signatures ||= {}
end
end

0 comments on commit ad1b581

Please sign in to comment.