Skip to content

Commit ad1b581

Browse files
committed
Basic signature support for Compiler2.
git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@9393 961051c9-f516-0410-bf72-c9f7e237a7b7
1 parent 7417037 commit ad1b581

File tree

2 files changed

+119
-9
lines changed

2 files changed

+119
-9
lines changed

Diff for: tool/compiler2.rb

+109-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'bitescript'
2+
require File.dirname(__FILE__) + '/signature'
23

34
RubyObject = org.jruby.RubyObject
45
RubyBasicObject = org.jruby.RubyBasicObject
@@ -7,6 +8,9 @@
78
IRubyObject = org.jruby.runtime.builtin.IRubyObject
89
ThreadContext = org.jruby.runtime.ThreadContext
910
LoadService = org.jruby.runtime.load.LoadService
11+
JClass = java.lang.Class
12+
JavaUtil = org.jruby.javasupport.JavaUtil
13+
JObject = java.lang.Object
1014

1115
JAVA_CLASSNAME = ARGV[0]
1216
RUBY_CLASSNAME = ARGV[1]
@@ -20,6 +24,20 @@
2024
require RUBY_FILENAME
2125
RUBY_CLASS = eval(RUBY_CLASSNAME)
2226

27+
BiteScript.bytecode_version = BiteScript::JAVA1_5
28+
29+
def first_local(params, instance = true)
30+
i = instance ? 1 : 0
31+
params.each do |param|
32+
if param == Java::long || param == Java::double
33+
i += 2
34+
else
35+
i += 1
36+
end
37+
end
38+
i
39+
end
40+
2341
file = BiteScript::FileBuilder.build("#{JAVA_CLASSNAME}.java.rb") do
2442
public_class JAVA_CLASSNAME, RubyObject do
2543
static_init do
@@ -41,31 +59,113 @@
4159

4260
for method_name in RUBY_CLASS.public_instance_methods(false) do
4361
method = RUBY_CLASS.instance_method(method_name)
44-
params = (method.arity < 0) ? [IRubyObject[]] : [IRubyObject] * method.arity
45-
public_method method_name, IRubyObject, *params do
62+
signature = RUBY_CLASS.signatures[method_name]
63+
64+
if signature
65+
raise "signatures only supported for exact arities: #{RUBY_CLASS.to_s + '#' + method_name}" if method.arity < 0
66+
params = signature.keys[0]
67+
retval = signature[params]
68+
use_ji = true
69+
else
70+
params = (method.arity < 0) ? [IRubyObject[]] : [IRubyObject] * method.arity
71+
retval = IRubyObject
72+
end
73+
74+
public_method method_name, retval, *params do
4675
aload 0
4776
dup
4877
invokeinterface IRubyObject, "getRuntime", [Ruby]
78+
ruby_index = first_local(params)
79+
dup; astore ruby_index
4980
invokevirtual Ruby, "getCurrentContext", [ThreadContext]
5081
ldc method_name
5182
# TODO: arity-specific call
52-
if method.arity < 0
53-
# restarg or optarg, just pass array through
54-
aload 1
55-
else
56-
# all normal args, box them up
83+
if use_ji
84+
# We have a signature and need to use java integration logic
5785
ldc method.arity
5886
anewarray IRubyObject
5987
i = 1;
88+
index = 1
6089
1.upto(method.arity) do |i|
6190
dup
6291
ldc i - 1
63-
aload i
92+
aload ruby_index
93+
param_type = params[i - 1]
94+
if [boolean, byte, short, char, int].include? param_type
95+
iload index
96+
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, int]
97+
elsif long == param_type
98+
lload index
99+
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, long]
100+
index += 1
101+
elsif float == param_type
102+
fload index
103+
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, float]
104+
elsif double == param_type
105+
dload index
106+
invokestatic JavaUtil, "convertJavaToRuby", [IRubyObject, Ruby, double]
107+
index += 1
108+
else
109+
aload i
110+
invokestatic JavaUtil, "convertJavaToUsableRubyObject", [IRubyObject, Ruby, object]
111+
end
64112
aastore
113+
index += 1
114+
end
115+
else
116+
if method.arity < 0
117+
# restarg or optarg, just pass array through
118+
aload 1
119+
else
120+
# all normal args, box them up
121+
ldc method.arity
122+
anewarray IRubyObject
123+
i = 1;
124+
1.upto(method.arity) do |i|
125+
dup
126+
ldc i - 1
127+
aload i
128+
aastore
129+
end
65130
end
66131
end
67132
invokevirtual RubyBasicObject, "callMethod", [IRubyObject, ThreadContext, string, IRubyObject[]]
68-
areturn
133+
if use_ji
134+
if boolean == retval
135+
invokestatic JavaUtil, "convertRubyToJavaBoolean", [boolean, IRubyObject]
136+
ireturn
137+
elsif byte == retval
138+
invokestatic JavaUtil, "convertRubyToJavaByte", [byte, IRubyObject]
139+
ireturn
140+
elsif short == retval
141+
invokestatic JavaUtil, "convertRubyToJavaShort", [short, IRubyObject]
142+
ireturn
143+
elsif char == retval
144+
invokestatic JavaUtil, "convertRubyToJavaChar", [char, IRubyObject]
145+
ireturn
146+
elsif int == retval
147+
invokestatic JavaUtil, "convertRubyToJavaInt", [int, IRubyObject]
148+
ireturn
149+
elsif long == retval
150+
invokestatic JavaUtil, "convertRubyToJavaLong", [long, IRubyObject]
151+
lreturn
152+
elsif float == retval
153+
invokestatic JavaUtil, "convertRubyToJavaFloat", [float, IRubyObject]
154+
freturn
155+
elsif double == retval
156+
invokestatic JavaUtil, "convertRubyToJavaDouble", [double, IRubyObject]
157+
dreturn
158+
elsif retval == void
159+
pop
160+
returnvoid
161+
else
162+
ldc retval
163+
invokestatic JavaUtil, "convertRubyToJava", [JObject, IRubyObject, JClass]
164+
areturn
165+
end
166+
else
167+
areturn
168+
end
69169
end
70170
end
71171
end

Diff for: tool/signature.rb

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Class
2+
def signature(name, signature)
3+
name = name.to_s
4+
signatures[name] = signature
5+
end
6+
7+
def signatures
8+
@signatures ||= {}
9+
end
10+
end

0 commit comments

Comments
 (0)