Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' into codecache

  • Loading branch information...
commit 79ce62661f08447a75a03efcd710a531e765ff0b 2 parents 7fee4a2 + ef6c935
@headius headius authored
Showing with 1,509 additions and 413 deletions.
  1. +1 −1  bin/ast
  2. +1 −1  bin/gem.bat
  3. +1 −1  bin/jirb.bat
  4. +1 −1  bin/jirb_swing.bat
  5. +3 −1 bin/jrubyd.bat
  6. +1 −1  bin/rake.bat
  7. +1 −1  bin/rdoc.bat
  8. +1 −1  bin/ri.bat
  9. +14 −5 build.xml
  10. BIN  build_lib/jffi-x86_64-Windows.jar
  11. BIN  build_lib/jnr-posix.jar
  12. +6 −2 default.build.properties
  13. +1 −1  lib/ruby/1.8/Win32API.rb
  14. +0 −1  lib/ruby/site_ruby/shared/builtin/javasupport.rb
  15. +0 −27 lib/ruby/site_ruby/shared/builtin/javasupport/proxy/interface.rb
  16. +3 −1 lib/ruby/site_ruby/shared/ffi/library.rb
  17. +1 −0  lib/ruby/site_ruby/shared/ffi/times.rb
  18. +1 −1  maven/jruby-complete/pom.xml
  19. +1 −1  maven/jruby/pom.xml
  20. +1 −1  pom.xml
  21. +2 −2 rubyspecs.revision
  22. +3 −5 spec/java_integration/types/coercion_spec.rb
  23. +0 −6 spec/jruby.1.8.mspec
  24. +1 −0  spec/tags/1.8/ruby/core/proc/call_tags.txt
  25. +1 −0  spec/tags/1.8/ruby/core/proc/element_reference_tags.txt
  26. +422 −0 src/org/jruby/BasicObjectStub.java
  27. +3 −0  src/org/jruby/RubyArray.java
  28. +2 −0  src/org/jruby/RubyBignum.java
  29. +4 −0 src/org/jruby/RubyBinding.java
  30. +2 −0  src/org/jruby/RubyBoolean.java
  31. +6 −0 src/org/jruby/RubyClass.java
  32. +2 −0  src/org/jruby/RubyComplex.java
  33. +5 −0 src/org/jruby/RubyContinuation.java
  34. +1 −0  src/org/jruby/RubyConverter.java
  35. +4 −0 src/org/jruby/RubyDir.java
  36. +1 −0  src/org/jruby/RubyEncoding.java
  37. +4 −0 src/org/jruby/RubyException.java
  38. +5 −0 src/org/jruby/RubyFile.java
  39. +3 −0  src/org/jruby/RubyFixnum.java
  40. +3 −0  src/org/jruby/RubyFloat.java
  41. +3 −0  src/org/jruby/RubyHash.java
  42. +4 −0 src/org/jruby/RubyIO.java
  43. +7 −0 src/org/jruby/RubyInstanceConfig.java
  44. +5 −0 src/org/jruby/RubyInteger.java
  45. +1 −12 src/org/jruby/RubyKernel.java
  46. +4 −0 src/org/jruby/RubyMatchData.java
  47. +4 −0 src/org/jruby/RubyMethod.java
  48. +1 −0  src/org/jruby/RubyModule.java
  49. +1 −0  src/org/jruby/RubyNil.java
  50. +5 −1 src/org/jruby/RubyNumeric.java
  51. +2 −1  src/org/jruby/RubyObject.java
  52. +4 −0 src/org/jruby/RubyProc.java
  53. +5 −0 src/org/jruby/RubyRange.java
  54. +2 −0  src/org/jruby/RubyRational.java
  55. +3 −0  src/org/jruby/RubyRegexp.java
  56. +6 −0 src/org/jruby/RubyString.java
  57. +3 −1 src/org/jruby/RubyStruct.java
  58. +1 −0  src/org/jruby/RubySymbol.java
  59. +4 −0 src/org/jruby/RubyThread.java
  60. +3 −0  src/org/jruby/RubyThreadGroup.java
  61. +3 −0  src/org/jruby/RubyTime.java
  62. +4 −0 src/org/jruby/RubyUnboundMethod.java
  63. +120 −0 src/org/jruby/compiler/util/BasicObjectStubGenerator.java
  64. +1 −1  src/org/jruby/ext/ffi/AutoPointer.java
  65. +29 −7 src/org/jruby/ext/ffi/CallbackInfo.java
  66. +1 −1  src/org/jruby/ext/ffi/Platform.java
  67. +1 −1  src/org/jruby/ext/ffi/StructLayout.java
  68. +4 −2 src/org/jruby/ext/ffi/jffi/CallbackManager.java
  69. +3 −1 src/org/jruby/ext/ffi/jffi/DefaultMethodFactory.java
  70. +2 −1  src/org/jruby/ext/ffi/jffi/FFIUtil.java
  71. +2 −1  src/org/jruby/ext/ffi/jffi/Factory.java
  72. +9 −11 src/org/jruby/ext/ffi/jffi/JFFIInvoker.java
  73. +1 −1  src/org/jruby/ext/ffi/jffi/VariadicInvoker.java
  74. +368 −45 src/org/jruby/java/MiniJava.java
  75. +0 −1  src/org/jruby/java/proxies/ConcreteJavaProxy.java
  76. +23 −29 src/org/jruby/java/proxies/InterfaceJavaProxy.java
  77. +175 −188 src/org/jruby/java/proxies/JavaInterfaceTemplate.java
  78. +94 −22 src/org/jruby/javasupport/Java.java
  79. +3 −0  src/org/jruby/javasupport/JavaClass.java
  80. +1 −1  src/org/jruby/javasupport/JavaConstructor.java
  81. +0 −11 src/org/jruby/javasupport/JavaSupport.java
  82. +9 −5 src/org/jruby/javasupport/util/RuntimeHelpers.java
  83. +7 −7 src/org/jruby/jruby.properties
  84. +1 −0  src/org/jruby/libraries/RbConfigLibrary.java
  85. +13 −1 src/org/jruby/runtime/ClassIndex.java
  86. +38 −0 src/org/jruby/runtime/builtin/RubyJavaObject.java
  87. +6 −0 src/org/jruby/util/CodegenUtils.java
  88. +11 −0 test/test_kernel.rb
View
2  bin/ast
@@ -59,7 +59,7 @@ end
if ARGV.length > 1
puts "You may only specify one script (see --help)"
exit 0
-elsif ARGV == 1
+elsif ARGV.length == 1
if expression
puts "-e and a script is not a valid combination (see --help)"
exit 0
View
2  bin/gem.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "gem" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
2  bin/jirb.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "jirb" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
2  bin/jirb_swing.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "jirb_swing" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
4 bin/jrubyd.bat
@@ -1,7 +1,9 @@
@ECHO OFF
+
@set debug_args=-J-Xdebug -J-Xrunjdwp:transport=dt_shmem,server=y,suspend=y
+
IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby.exe" %debug_args% %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby.exe" %debug_args% "%~dpn0" %*
+@"%~dp0jruby.exe" %debug_args% "%~dpn0" %*
View
2  bin/rake.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "rake" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
2  bin/rdoc.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "rdoc" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
2  bin/ri.bat
@@ -3,4 +3,4 @@ IF NOT "%~f0" == "~f0" GOTO :WinNT
@"jruby" -S "ri" %1 %2 %3 %4 %5 %6 %7 %8 %9
GOTO :EOF
:WinNT
-@"jruby" "%~dpn0" %*
+@"%~dp0jruby.exe" "%~dpn0" %*
View
19 build.xml
@@ -147,10 +147,17 @@
<include name="**/*.properties"/>
</fileset>
<filterset>
- <filter token="os.arch" value="${os.arch}"/>
+ <filter token="version.ruby.major" value="${version.ruby.major}"/>
+ <filter token="version.ruby" value="${version.ruby}"/>
+ <filter token="version.ruby.patchlevel" value="${version.ruby.patchlevel}"/>
+ <filter token="version.ruby1_9.major" value="${version.ruby1_9.major}"/>
+ <filter token="version.ruby1_9" value="${version.ruby1_9}"/>
+ <filter token="version.ruby1_9.patchlevel" value="${version.ruby1_9.patchlevel}"/>
+ <filter token="build.date" value="${build.date}"/>
+ <filter token="version.jruby" value="${version.jruby}"/>
<filter token="java.specification.version" value="${java.specification.version}"/>
<filter token="javac.version" value="${javac.version}"/>
- <filter token="build.date" value="${build.date}"/>
+ <filter token="os.arch" value="${os.arch}"/>
</filterset>
</copy>
</target>
@@ -297,6 +304,7 @@
<zipfileset src="${build.lib.dir}/jffi-i386-OpenBSD.jar"/>
<zipfileset src="${build.lib.dir}/jffi-x86_64-OpenBSD.jar"/>
<zipfileset src="${build.lib.dir}/jffi-i386-Windows.jar"/>
+ <zipfileset src="${build.lib.dir}/jffi-x86_64-Windows.jar"/>
<zipfileset src="${build.lib.dir}/jffi-s390x-Linux.jar"/>
<zipfileset src="${build.lib.dir}/joda-time-1.6.jar"/>
<zipfileset src="${build.lib.dir}/dynalang-0.3.jar"/>
@@ -443,6 +451,7 @@
<jarjar destfile="${dest.lib.dir}/${filename}">
<fileset dir="${jruby.classes.dir}"/>
<fileset dir="${build.dir}/jar-complete">
+ <exclude name="META-INF/jruby.home/lib/ruby/site_ruby/shared/builtin/**"/>
<exclude name="META-INF/jruby.home/lib/ruby/1.9/**"/>
</fileset>
<zipfileset src="${build.lib.dir}/asm-3.2.jar"/>
@@ -990,12 +999,12 @@
<sysproperty key="jruby.thread.pool.enabled" value="@{thread.pooling}"/>
<sysproperty key="jruby.reflection" value="@{reflection}"/>
<sysproperty key="jruby.launch.inproc" value="@{inproc}"/>
- <sysproperty key="emma.coverage.out.file" value="${test.results.dir}/coverage.emma" />
- <sysproperty key="emma.coverage.out.merge" value="true" />
+ <sysproperty key="emma.coverage.out.file" value="${test.results.dir}/coverage.emma" />
+ <sysproperty key="emma.coverage.out.merge" value="true" />
<sysproperty key="emma.verbosity.level" value="silent" />
<arg line="@{jruby.args}"/>
- <arg value="${base.dir}/bin/rake"/>
+ <arg line="-S rake"/>
<arg line="@{rake.targets}"/>
</java>
</sequential>
View
BIN  build_lib/jffi-x86_64-Windows.jar
Binary file not shown
View
BIN  build_lib/jnr-posix.jar
Binary file not shown
View
8 default.build.properties
@@ -33,7 +33,11 @@ jruby.test.memory=512M
jruby.test.jvm=java
ruby.executable=/usr/bin/ruby
install4j.executable=/Applications/install4j\ 4/bin/install4jc
-version.jruby=1.5.0.dev
+version.ruby=1.8.7
version.ruby.major=1.8
version.ruby.minor=7
-
+version.ruby.patchlevel=174
+version.ruby1_9.major=1.9
+version.ruby1_9=1.9.2dev
+version.ruby1_9.patchlevel=24787
+version.jruby=1.5.0.dev
View
2  lib/ruby/1.8/Win32API.rb
@@ -22,7 +22,7 @@ def self.find_type(name)
def self.map_types(spec)
if spec.kind_of?(String)
- spec.split //
+ spec.split(//)
elsif spec.kind_of?(Array)
spec
else
View
1  lib/ruby/site_ruby/shared/builtin/javasupport.rb
@@ -35,7 +35,6 @@
require 'builtin/javasupport/java'
require 'builtin/javasupport/proxy/array'
-require 'builtin/javasupport/proxy/interface'
require 'builtin/javasupport/utilities/base'
require 'builtin/javasupport/utilities/array'
require 'builtin/javasupport/core_ext'
View
27 lib/ruby/site_ruby/shared/builtin/javasupport/proxy/interface.rb
@@ -1,27 +0,0 @@
-class JavaInterfaceExtender
- def initialize(java_class_name, &block)
- # don't really need @java_class here any more, keeping around
- # in case any users use this class directly
- @java_class = Java::JavaClass.for_name(java_class_name)
- @block = block
- end
-
- def extend_proxy(proxy_class)
- proxy_class.class_eval(&@block)
- end
-end
-
-class InterfaceJavaProxy < JavaProxy
- def self.impl(*meths, &block)
- block = lambda {|*args| send(:method_missing, *args) } unless block
-
- interface = JavaUtilities.get_interface_module java_class
- Class.new(self) do
- include interface
- define_method(:method_missing) do |name, *args|
- return block.call(name, *args) if meths.empty? || meths.include?(name)
- super
- end
- end.new
- end
-end
View
4 lib/ruby/site_ruby/shared/ffi/library.rb
@@ -136,10 +136,12 @@ def callback(*args)
else
[ nil, args[0], args[1] ]
end
+
options = Hash.new
options[:convention] = defined?(@ffi_convention) ? @ffi_convention : :default
options[:enums] = @ffi_enums if defined?(@ffi_enums)
- cb = FFI::CallbackInfo.new(find_type(ret), params.map { |e| find_type(e) })
+
+ cb = FFI::CallbackInfo.new(find_type(ret), params.map { |e| find_type(e) }, options)
# Add to the symbol -> type map (unless there was no name)
unless name.nil?
View
1  lib/ruby/site_ruby/shared/ffi/times.rb
@@ -6,6 +6,7 @@ class Foreign
SC_CLK_TCK = com.kenai.constantine.platform.Sysconf::_SC_CLK_TCK.value
extend FFI::Library
+ ffi_lib FFI::Library::LIBC
class Times < FFI::Struct
layout \
:utime => :long,
View
2  maven/jruby-complete/pom.xml
@@ -72,7 +72,7 @@
<dependency>
<groupId>org.jruby.ext.posix</groupId>
<artifactId>jnr-posix</artifactId>
- <version>1.0.5</version>
+ <version>1.0.8</version>
<scope>provided</scope>
</dependency>
<dependency>
View
2  maven/jruby/pom.xml
@@ -72,7 +72,7 @@
<dependency>
<groupId>org.jruby.ext.posix</groupId>
<artifactId>jnr-posix</artifactId>
- <version>1.0.5</version>
+ <version>1.0.8</version>
<scope>provided</scope>
</dependency>
<dependency>
View
2  pom.xml
@@ -8,7 +8,7 @@
<version>1.5.0dev</version>
<name>JRuby Shared</name>
<url>http://www.jruby.org/</url>
- <description>A 1.8.5 compatible Ruby interpreter written in 100% pure Java</description>
+ <description>A 1.8.7 compatible Ruby interpreter written in 100% pure Java</description>
<issueManagement>
<system>JIRA</system>
View
4 rubyspecs.revision
@@ -1,6 +1,6 @@
# These are the pointers to the 'stable/frozen' versions of
# mspec and rubyspecs, used to for our CI runs.
-mspec.revision=bcec47c70e0678a29fd0c1345358c4daf7b971a3
+mspec.revision=1521f846a8e9c6da51697e962c39dc1f3c0fc473
-rubyspecs.revision=9b8d16adaa79a5b627f76b968d2e730b1ae3476f
+rubyspecs.revision=515547fc2e2024d3730fe6af925f37781e6cbd0e
View
8 spec/java_integration/types/coercion_spec.rb
@@ -424,11 +424,9 @@ def receiveByte(obj)
vri.result.should == obj
vri.result.class.should == Fixnum
- pending "char appears to be getting signed/unsigned-garbled" do
- vri_handler.receiveCharObj(obj).should == obj
- vri.result.should == obj
- vri.result.class.should == Fixnum
- end
+ vri_handler.receiveCharObj(obj).should == obj
+ vri.result.should == obj
+ vri.result.class.should == Fixnum
vri_handler.receiveIntObj(obj).should == obj
vri.result.should == obj
View
6 spec/jruby.1.8.mspec
@@ -19,12 +19,6 @@ class MSpecScript
set :core, [
SPEC_DIR + '/core',
- # FIXME: Temporarily exclusion until JRUBY-4180 is fixed.
- '^' + SPEC_DIR + '/core/proc/case_compare_spec.rb',
- '^' + SPEC_DIR + '/core/proc/element_reference_spec.rb',
- '^' + SPEC_DIR + '/core/proc/yield_spec.rb',
- '^' + SPEC_DIR + '/core/proc/call_spec.rb',
-
# 1.9
'^' + SPEC_DIR + '/core/basicobject'
]
View
1  spec/tags/1.8/ruby/core/proc/call_tags.txt
@@ -0,0 +1 @@
+fails(JRUBY-4180):Proc#call can receive block arguments
View
1  spec/tags/1.8/ruby/core/proc/element_reference_tags.txt
@@ -0,0 +1 @@
+fails(JRUBY-4180):Proc#[] can receive block arguments
View
422 src/org/jruby/BasicObjectStub.java
@@ -0,0 +1,422 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Charles O Nutter <headius@headius.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+package org.jruby;
+
+import java.util.Collections;
+import java.util.List;
+import org.jruby.javasupport.util.RuntimeHelpers;
+import org.jruby.runtime.Block;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.builtin.InstanceVariables;
+import org.jruby.runtime.builtin.InternalVariables;
+import org.jruby.runtime.builtin.RubyJavaObject;
+import org.jruby.runtime.builtin.Variable;
+import org.jruby.util.TypeConverter;
+
+public final class BasicObjectStub {
+ public static IRubyObject callSuper(IRubyObject self, ThreadContext context, IRubyObject[] args, Block block) {
+ return RuntimeHelpers.invokeSuper(context, self, args, block);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, String name) {
+ return RuntimeHelpers.invoke(context, self, name);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, String name, IRubyObject arg) {
+ return RuntimeHelpers.invoke(context, self, name, arg);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, String name, IRubyObject[] args) {
+ return RuntimeHelpers.invoke(context, self, name, args);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, String name, IRubyObject[] args, Block block) {
+ return RuntimeHelpers.invoke(context, self, name, args, block);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, int methodIndex, String name) {
+ return RuntimeHelpers.invoke(context, self, name);
+ }
+
+ public static IRubyObject callMethod(IRubyObject self, ThreadContext context, int methodIndex, String name, IRubyObject arg) {
+ return RuntimeHelpers.invoke(context, self, name, arg);
+ }
+
+ public static boolean isNil(IRubyObject self) {
+ return false;
+ }
+
+ public static boolean isTrue(IRubyObject self) {
+ return true;
+ }
+
+ public static boolean isTaint(IRubyObject self) {
+ return false;
+ }
+
+ public static void setTaint(IRubyObject self, boolean b) {
+ }
+
+ public static IRubyObject infectBy(IRubyObject self, IRubyObject obj) {
+ return self;
+ }
+
+ public static boolean isFrozen(IRubyObject self) {
+ return false;
+ }
+
+ public static void setFrozen(IRubyObject self, boolean b) {
+ }
+
+ public static boolean isUntrusted(IRubyObject self) {
+ return false;
+ }
+
+ public static void setUntrusted(IRubyObject self, boolean b) {
+ }
+
+ public static boolean isImmediate(IRubyObject self) {
+ return false;
+ }
+
+ public static RubyClass getMetaClass(IRubyObject self) {
+ if (self instanceof RubyBasicObject) {
+ return ((RubyBasicObject)self).getMetaClass();
+ } else if (self instanceof RubyJavaObject) {
+ return ((RubyJavaObject)self).getMetaClass();
+ } else {
+ throw new RuntimeException("unknown object type in BasicObjectStuff.getMetaClass: " + self.getClass());
+ }
+ }
+
+ public static RubyClass getSingletonClass(IRubyObject self) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public static RubyClass getType(IRubyObject self) {
+ return getMetaClass(self).getRealClass();
+ }
+
+ public static boolean respondsTo(IRubyObject self, String name) {
+ if(getMetaClass(self).searchMethod("respond_to?") == getRuntime(self).getRespondToMethod()) {
+ return getMetaClass(self).isMethodBound(name, false);
+ } else {
+ return callMethod(self, getRuntime(self).getCurrentContext(), "respond_to?", getRuntime(self).newSymbol(name)).isTrue();
+ }
+ }
+
+ public static Ruby getRuntime(IRubyObject self) {
+ return getMetaClass(self).getClassRuntime();
+ }
+
+ public static Class getJavaClass(IRubyObject self) {
+ return self.getClass();
+ }
+
+ public static String asJavaString(IRubyObject self) {
+ IRubyObject asString = checkStringType(self);
+ if(!asString.isNil()) return ((RubyString)asString).asJavaString();
+ throw getRuntime(self).newTypeError(inspect(self).toString() + " is not a string");
+ }
+
+ public static RubyString asString(IRubyObject self) {
+ IRubyObject str = RuntimeHelpers.invoke(getRuntime(self).getCurrentContext(), self, "to_s");
+
+ if (!(str instanceof RubyString)) return (RubyString)anyToString(self);
+ if (isTaint(self)) str.setTaint(true);
+ return (RubyString) str;
+ }
+
+ public static RubyArray convertToArray(IRubyObject self) {
+ return (RubyArray) TypeConverter.convertToType(self, getRuntime(self).getArray(), "to_ary");
+ }
+
+ public static RubyHash convertToHash(IRubyObject self) {
+ return (RubyHash)TypeConverter.convertToType(self, getRuntime(self).getHash(), "to_hash");
+ }
+
+ public static RubyFloat convertToFloat(IRubyObject self) {
+ return (RubyFloat) TypeConverter.convertToType(self, getRuntime(self).getFloat(), "to_f");
+ }
+
+ public static RubyInteger convertToInteger(IRubyObject self) {
+ return convertToInteger(self, "to_int");
+ }
+
+ public static RubyInteger convertToInteger(IRubyObject self, int convertMethodIndex, String convertMethod) {
+ return convertToInteger(self, convertMethod);
+ }
+
+ public static RubyInteger convertToInteger(IRubyObject self, String convertMethod) {
+ IRubyObject val = TypeConverter.convertToType(self, getRuntime(self).getInteger(), convertMethod, true);
+ if (!(val instanceof RubyInteger)) throw getRuntime(self).newTypeError(getMetaClass(self).getName() + "#" + convertMethod + " should return Integer");
+ return (RubyInteger)val;
+ }
+
+ public static RubyString convertToString(IRubyObject self) {
+ return (RubyString) TypeConverter.convertToType(self, getRuntime(self).getString(), "to_str");
+ }
+
+ public static IRubyObject anyToString(IRubyObject self) {
+ String cname = getMetaClass(self).getRealClass().getName();
+ /* 6:tags 16:addr 1:eos */
+ RubyString str = getRuntime(self).newString("#<" + cname + ":0x" + Integer.toHexString(System.identityHashCode(self)) + ">");
+ str.setTaint(isTaint(self));
+ return str;
+ }
+
+ public static IRubyObject checkStringType(IRubyObject self) {
+ IRubyObject str = TypeConverter.convertToTypeWithCheck(self, getRuntime(self).getString(), "to_str");
+ if(!str.isNil() && !(str instanceof RubyString)) {
+ str = RubyString.newEmptyString(getRuntime(self));
+ }
+ return str;
+ }
+
+ public static IRubyObject checkArrayType(IRubyObject self) {
+ return TypeConverter.convertToTypeWithCheck(self, getRuntime(self).getArray(), "to_ary");
+ }
+
+ public static Object toJava(IRubyObject self, Class cls) {
+ if (cls.isAssignableFrom(self.getClass())) {
+ return self;
+ } else {
+ throw getRuntime(self).newTypeError("could not convert " + self.getClass() + " to " + cls);
+ }
+ }
+
+ public static IRubyObject dup(IRubyObject self) {
+ // TODO: java.lang.Object.clone?
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public static IRubyObject inspect(IRubyObject self) {
+ Ruby runtime = getRuntime(self);
+ if (hasVariables(self)) {
+ StringBuilder part = new StringBuilder();
+ String cname = getMetaClass(self).getRealClass().getName();
+ part.append("#<").append(cname).append(":0x");
+ part.append(Integer.toHexString(System.identityHashCode(self)));
+
+ if (runtime.isInspecting(self)) {
+ /* 6:tags 16:addr 1:eos */
+ part.append(" ...>");
+ return runtime.newString(part.toString());
+ }
+ try {
+ runtime.registerInspecting(self);
+ return runtime.newString(inspectObj(self, part).toString());
+ } finally {
+ runtime.unregisterInspecting(self);
+ }
+ }
+
+ return RuntimeHelpers.invoke(runtime.getCurrentContext(), self, "to_s");
+ }
+
+
+ /** inspect_obj
+ *
+ * The internal helper method that takes care of the part of the
+ * inspection that inspects instance variables.
+ */
+ private static StringBuilder inspectObj(IRubyObject self, StringBuilder part) {
+ ThreadContext context = getRuntime(self).getCurrentContext();
+ String sep = "";
+
+ for (Variable<IRubyObject> ivar : getInstanceVariables(self).getInstanceVariableList()) {
+ part.append(sep).append(" ").append(ivar.getName()).append("=");
+ part.append(ivar.getValue().callMethod(context, "inspect"));
+ sep = ",";
+ }
+ part.append(">");
+ return part;
+ }
+
+ public static IRubyObject rbClone(IRubyObject self) {
+ // TODO: java.lang.Object.clone?
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public static boolean isModule(IRubyObject self) {
+ return false;
+ }
+
+ public static boolean isClass(IRubyObject self) {
+ return false;
+ }
+
+ public static void dataWrapStruct(IRubyObject self, Object obj) {
+ }
+
+ public static Object dataGetStruct(IRubyObject self) {
+ return null;
+ }
+
+ public static Object dataGetStructChecked(IRubyObject self) {
+ return null;
+ }
+
+ public static IRubyObject id(IRubyObject self) {
+ return getRuntime(self).newFixnum(System.identityHashCode(self));
+ }
+
+ public static IRubyObject op_equal(IRubyObject self, ThreadContext context, IRubyObject other) {
+ return getRuntime(self).newBoolean(self == other);
+ }
+
+ public static IRubyObject op_eqq(IRubyObject self, ThreadContext context, IRubyObject other) {
+ return getRuntime(self).newBoolean(self == other);
+ }
+
+ public static boolean eql(IRubyObject self, IRubyObject other) {
+ return self == other;
+ }
+
+ public static void addFinalizer(IRubyObject self, IRubyObject finalizer) {
+ }
+
+ public static void removeFinalizers(IRubyObject self) {
+ }
+
+ public static boolean hasVariables(IRubyObject self) {
+ return false;
+ }
+
+ public static int getVariableCount(IRubyObject self) {
+ return 0;
+ }
+
+ public static void syncVariables(IRubyObject self, List<Variable<Object>> variables) {
+ }
+
+ public static List<Variable<Object>> getVariableList(IRubyObject self) {
+ return Collections.EMPTY_LIST;
+ }
+
+ public static class DummyInstanceVariables implements InstanceVariables {
+ private final IRubyObject nil;
+
+ public DummyInstanceVariables(IRubyObject nil) {
+ this.nil = nil;
+ }
+
+ public boolean hasInstanceVariable(String name) {
+ return false;
+ }
+
+ public boolean fastHasInstanceVariable(String internedName) {
+ return false;
+ }
+
+ public IRubyObject getInstanceVariable(String name) {
+ return nil;
+ }
+
+ public IRubyObject fastGetInstanceVariable(String internedName) {
+ return nil;
+ }
+
+ public IRubyObject setInstanceVariable(String name, IRubyObject value) {
+ return value;
+ }
+
+ public IRubyObject fastSetInstanceVariable(String internedName, IRubyObject value) {
+ return value;
+ }
+
+ public IRubyObject removeInstanceVariable(String name) {
+ return nil;
+ }
+
+ public List<Variable<IRubyObject>> getInstanceVariableList() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public List<String> getInstanceVariableNameList() {
+ return Collections.EMPTY_LIST;
+ }
+
+ public void copyInstanceVariablesInto(InstanceVariables other) {
+ }
+
+ }
+
+ public static InstanceVariables getInstanceVariables(IRubyObject self) {
+ // TODO: cache in runtime?
+ return new DummyInstanceVariables(getRuntime(self).getNil());
+ }
+
+ public static class DummyInternalVariables implements InternalVariables {
+ public boolean hasInternalVariable(String name) {
+ return false;
+ }
+
+ public boolean fastHasInternalVariable(String internedName) {
+ return false;
+ }
+
+ public Object getInternalVariable(String name) {
+ return null;
+ }
+
+ public Object fastGetInternalVariable(String internedName) {
+ return null;
+ }
+
+ public void setInternalVariable(String name, Object value) {
+ }
+
+ public void fastSetInternalVariable(String internedName, Object value) {
+ }
+
+ public Object removeInternalVariable(String name) {
+ return null;
+ }
+ }
+ public static final InternalVariables DUMMY_INTERNAL_VARIABLES = new DummyInternalVariables();
+
+ public static InternalVariables getInternalVariables(IRubyObject self) {
+ return DUMMY_INTERNAL_VARIABLES;
+ }
+
+ public static List<String> getVariableNameList(IRubyObject self) {
+ return Collections.EMPTY_LIST;
+ }
+
+ public static void copySpecialInstanceVariables(IRubyObject self, IRubyObject clone) {
+ }
+
+ public static Object getVariable(IRubyObject self, int index) {
+ return null;
+ }
+
+ public static void setVariable(IRubyObject self, int index, Object value) {
+ }
+}
View
3  src/org/jruby/RubyArray.java
@@ -84,7 +84,10 @@
public static RubyClass createArrayClass(Ruby runtime) {
RubyClass arrayc = runtime.defineClass("Array", runtime.getObject(), ARRAY_ALLOCATOR);
runtime.setArray(arrayc);
+
arrayc.index = ClassIndex.ARRAY;
+ arrayc.setReifiedClass(RubyArray.class);
+
arrayc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
2  src/org/jruby/RubyBignum.java
@@ -56,7 +56,9 @@ public static RubyClass createBignumClass(Ruby runtime) {
RubyClass bignum = runtime.defineClass("Bignum", runtime.getInteger(),
ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setBignum(bignum);
+
bignum.index = ClassIndex.BIGNUM;
+ bignum.setReifiedClass(RubyBignum.class);
bignum.defineAnnotatedMethods(RubyBignum.class);
View
4 src/org/jruby/RubyBinding.java
@@ -37,6 +37,7 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Binding;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.Frame;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
@@ -71,6 +72,9 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
public static RubyClass createBindingClass(Ruby runtime) {
RubyClass bindingClass = runtime.defineClass("Binding", runtime.getObject(), BINDING_ALLOCATOR);
runtime.setBinding(bindingClass);
+
+ bindingClass.index = ClassIndex.BINDING;
+ bindingClass.setReifiedClass(RubyBinding.class);
bindingClass.defineAnnotatedMethods(RubyBinding.class);
bindingClass.getSingletonClass().undefineMethod("new");
View
2  src/org/jruby/RubyBoolean.java
@@ -78,6 +78,7 @@ public static RubyClass createFalseClass(Ruby runtime) {
RubyClass falseClass = runtime.defineClass("FalseClass", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setFalseClass(falseClass);
falseClass.index = ClassIndex.FALSE;
+ falseClass.setReifiedClass(RubyBoolean.class);
falseClass.defineAnnotatedMethods(False.class);
@@ -90,6 +91,7 @@ public static RubyClass createTrueClass(Ruby runtime) {
RubyClass trueClass = runtime.defineClass("TrueClass", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setTrueClass(trueClass);
trueClass.index = ClassIndex.TRUE;
+ trueClass.setReifiedClass(RubyBoolean.class);
trueClass.defineAnnotatedMethods(True.class);
View
6 src/org/jruby/RubyClass.java
@@ -84,6 +84,7 @@
public class RubyClass extends RubyModule {
public static void createClassClass(Ruby runtime, RubyClass classClass) {
classClass.index = ClassIndex.CLASS;
+ classClass.setReifiedClass(RubyClass.class);
classClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
@@ -312,6 +313,7 @@ protected RubyClass(Ruby runtime, RubyClass superClazz) {
superClass = superClazz;
marshal = superClazz.marshal; // use parent's marshal
superClazz.addSubclass(this);
+ allocator = superClazz.allocator;
infectBy(superClass);
}
@@ -1177,6 +1179,10 @@ public synchronized void reify(String classDumpDir) {
reifiedClass = result;
}
+ public void setReifiedClass(Class newReifiedClass) {
+ this.reifiedClass = newReifiedClass;
+ }
+
public Class getReifiedClass() {
return reifiedClass;
}
View
2  src/org/jruby/RubyComplex.java
@@ -82,6 +82,8 @@ public static RubyClass createComplexClass(Ruby runtime) {
runtime.setComplex(complexc);
complexc.index = ClassIndex.COMPLEX;
+ complexc.setReifiedClass(RubyComplex.class);
+
complexc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
5 src/org/jruby/RubyContinuation.java
@@ -30,6 +30,7 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -54,6 +55,10 @@ public synchronized Throwable fillInStackTrace() {
public static void createContinuation(Ruby runtime) {
RubyClass cContinuation = runtime.defineClass("Continuation",runtime.getObject(),runtime.getObject().getAllocator());
+
+ cContinuation.index = ClassIndex.CONTINUATION;
+ cContinuation.setReifiedClass(RubyContinuation.class);
+
cContinuation.defineAnnotatedMethods(RubyContinuation.class);
cContinuation.getSingletonClass().undefineMethod("new");
View
1  src/org/jruby/RubyConverter.java
@@ -37,6 +37,7 @@ public static RubyClass createConverterClass(Ruby runtime) {
RubyClass converterc = runtime.defineClassUnder("Converter", runtime.getClass("Data"), CONVERTER_ALLOCATOR, runtime.getEncoding());
runtime.setConverter(converterc);
converterc.index = ClassIndex.CONVERTER;
+ converterc.setReifiedClass(RubyConverter.class);
converterc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
4 src/org/jruby/RubyDir.java
@@ -44,6 +44,7 @@
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -78,6 +79,9 @@ public static RubyClass createDirClass(Ruby runtime) {
RubyClass dirClass = runtime.defineClass("Dir", runtime.getObject(), DIR_ALLOCATOR);
runtime.setDir(dirClass);
+ dirClass.index = ClassIndex.DIR;
+ dirClass.setReifiedClass(RubyDir.class);
+
dirClass.includeModule(runtime.getEnumerable());
dirClass.defineAnnotatedMethods(RubyDir.class);
View
1  src/org/jruby/RubyEncoding.java
@@ -50,6 +50,7 @@ public static RubyClass createEncodingClass(Ruby runtime) {
RubyClass encodingc = runtime.defineClass("Encoding", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setEncoding(encodingc);
encodingc.index = ClassIndex.ENCODING;
+ encodingc.setReifiedClass(RubyEncoding.class);
encodingc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
4 src/org/jruby/RubyException.java
@@ -43,6 +43,7 @@
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ObjectMarshal;
import org.jruby.runtime.ThreadContext;
@@ -120,6 +121,9 @@ public static RubyClass createExceptionClass(Ruby runtime) {
RubyClass exceptionClass = runtime.defineClass("Exception", runtime.getObject(), EXCEPTION_ALLOCATOR);
runtime.setException(exceptionClass);
+ exceptionClass.index = ClassIndex.EXCEPTION;
+ exceptionClass.setReifiedClass(RubyException.class);
+
exceptionClass.setMarshal(EXCEPTION_MARSHAL);
exceptionClass.defineAnnotatedMethods(RubyException.class);
View
5 src/org/jruby/RubyFile.java
@@ -54,6 +54,7 @@
import org.jruby.anno.JRubyModule;
import org.jruby.ext.posix.util.Platform;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
@@ -196,6 +197,10 @@ public static RubyClass createFileClass(Ruby runtime) {
// Create Constants class
RubyModule constants = fileClass.defineModuleUnder("Constants");
runtime.setFile(fileClass);
+
+ fileClass.index = ClassIndex.FILE;
+ fileClass.setReifiedClass(RubyFile.class);
+
RubyString separator = runtime.newString("/");
ThreadContext context = runtime.getCurrentContext();
View
3  src/org/jruby/RubyFixnum.java
@@ -64,7 +64,10 @@ public static RubyClass createFixnumClass(Ruby runtime) {
RubyClass fixnum = runtime.defineClass("Fixnum", runtime.getInteger(),
ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setFixnum(fixnum);
+
fixnum.index = ClassIndex.FIXNUM;
+ fixnum.setReifiedClass(RubyFixnum.class);
+
fixnum.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
3  src/org/jruby/RubyFloat.java
@@ -87,7 +87,10 @@
public static RubyClass createFloatClass(Ruby runtime) {
RubyClass floatc = runtime.defineClass("Float", runtime.getNumeric(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setFloat(floatc);
+
floatc.index = ClassIndex.FLOAT;
+ floatc.setReifiedClass(RubyFloat.class);
+
floatc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
3  src/org/jruby/RubyHash.java
@@ -110,7 +110,10 @@
public static RubyClass createHashClass(Ruby runtime) {
RubyClass hashc = runtime.defineClass("Hash", runtime.getObject(), HASH_ALLOCATOR);
runtime.setHash(hashc);
+
hashc.index = ClassIndex.HASH;
+ hashc.setReifiedClass(RubyHash.class);
+
hashc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
4 src/org/jruby/RubyIO.java
@@ -324,6 +324,10 @@ public int getNativeTypeIndex() {
public static RubyClass createIOClass(Ruby runtime) {
RubyClass ioClass = runtime.defineClass("IO", runtime.getObject(), IO_ALLOCATOR);
+
+ ioClass.index = ClassIndex.IO;
+ ioClass.setReifiedClass(RubyIO.class);
+
ioClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
7 src/org/jruby/RubyInstanceConfig.java
@@ -570,8 +570,15 @@ public String getCopyrightString() {
public void processArguments(String[] arguments) {
new ArgumentProcessor(arguments).processArguments();
+ tryProcessArgumentsWithRubyopts(arguments);
+ }
+
+ private void tryProcessArgumentsWithRubyopts(String[] arguments) {
try {
String rubyopt = System.getenv("RUBYOPT");
+ if (rubyopt == null && environment != null && environment.containsKey("RUBYOPT")) {
+ rubyopt = environment.get("RUBYOPT").toString();
+ }
if (rubyopt != null) {
String[] rubyoptArgs = rubyopt.split("\\s+");
for (int i = 0; i < rubyoptArgs.length; i++) {
View
5 src/org/jruby/RubyInteger.java
@@ -43,6 +43,7 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockBody;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -61,6 +62,10 @@ public static RubyClass createIntegerClass(Ruby runtime) {
RubyClass integer = runtime.defineClass("Integer", runtime.getNumeric(),
ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setInteger(integer);
+
+ integer.index = ClassIndex.INTEGER;
+ integer.setReifiedClass(RubyInteger.class);
+
integer.kindOf = new RubyModule.KindOf() {
public boolean isKindOf(IRubyObject obj, RubyModule type) {
return obj instanceof RubyInteger;
View
13 src/org/jruby/RubyKernel.java
@@ -306,18 +306,7 @@ public static IRubyObject abort(ThreadContext context, IRubyObject recv, IRubyOb
@JRubyMethod(name = "Array", required = 1, module = true, visibility = PRIVATE)
public static IRubyObject new_array(ThreadContext context, IRubyObject recv, IRubyObject object) {
- IRubyObject value = object.checkArrayType();
-
- if (value.isNil()) {
- if (object.getMetaClass().searchMethod("to_a").getImplementationClass() != context.getRuntime().getKernel()) {
- value = object.callMethod(context, "to_a");
- if (!(value instanceof RubyArray)) throw context.getRuntime().newTypeError("`to_a' did not return Array");
- return value;
- } else {
- return context.getRuntime().newArray(object);
- }
- }
- return value;
+ return RuntimeHelpers.arrayValue(context, context.getRuntime(), object);
}
@JRubyMethod(name = "Complex", module = true, visibility = PRIVATE, compat = CompatVersion.RUBY1_9)
View
4 src/org/jruby/RubyMatchData.java
@@ -68,6 +68,10 @@
public static RubyClass createMatchDataClass(Ruby runtime) {
RubyClass matchDataClass = runtime.defineClass("MatchData", runtime.getObject(), MATCH_DATA_ALLOCATOR);
runtime.setMatchData(matchDataClass);
+
+ matchDataClass.index = ClassIndex.MATCHDATA;
+ matchDataClass.setReifiedClass(RubyMatchData.class);
+
runtime.defineGlobalConstant("MatchingData", matchDataClass);
matchDataClass.kindOf = new RubyModule.KindOf() {
@Override
View
4 src/org/jruby/RubyMethod.java
@@ -36,6 +36,7 @@
import org.jruby.exceptions.JumpException;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.MethodBlock;
import org.jruby.runtime.ObjectAllocator;
@@ -73,6 +74,9 @@ public static RubyClass createMethodClass(Ruby runtime) {
// TODO: NOT_ALLOCATABLE_ALLOCATOR is probably ok here. Confirm. JRUBY-415
RubyClass methodClass = runtime.defineClass("Method", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setMethod(methodClass);
+
+ methodClass.index = ClassIndex.METHOD;
+ methodClass.setReifiedClass(RubyMethod.class);
methodClass.defineAnnotatedMethods(RubyMethod.class);
View
1  src/org/jruby/RubyModule.java
@@ -124,6 +124,7 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
public static RubyClass createModuleClass(Ruby runtime, RubyClass moduleClass) {
moduleClass.index = ClassIndex.MODULE;
+ moduleClass.setReifiedClass(RubyModule.class);
moduleClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
1  src/org/jruby/RubyNil.java
@@ -61,6 +61,7 @@ public static RubyClass createNilClass(Ruby runtime) {
RubyClass nilClass = runtime.defineClass("NilClass", runtime.getObject(), NIL_ALLOCATOR);
runtime.setNilClass(nilClass);
nilClass.index = ClassIndex.NIL;
+ nilClass.setReifiedClass(RubyNil.class);
nilClass.defineAnnotatedMethods(RubyNil.class);
View
6 src/org/jruby/RubyNumeric.java
@@ -48,6 +48,7 @@
import org.jruby.javasupport.JavaUtil;
import org.jruby.javasupport.util.RuntimeHelpers;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
@@ -69,6 +70,9 @@ public static RubyClass createNumericClass(Ruby runtime) {
RubyClass numeric = runtime.defineClass("Numeric", runtime.getObject(), NUMERIC_ALLOCATOR);
runtime.setNumeric(numeric);
+ numeric.index = ClassIndex.NUMERIC;
+ numeric.setReifiedClass(RubyNumeric.class);
+
numeric.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
@@ -88,7 +92,7 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
}
};
- public static double DBL_EPSILON=2.2204460492503131e-16;
+ public static final double DBL_EPSILON=2.2204460492503131e-16;
private static IRubyObject convertToNum(double val, Ruby runtime) {
View
3  src/org/jruby/RubyObject.java
@@ -137,6 +137,7 @@ protected RubyObject(Ruby runtime, RubyClass metaClass, boolean useObjectSpace)
*/
public static RubyClass createObjectClass(Ruby runtime, RubyClass objectClass) {
objectClass.index = ClassIndex.OBJECT;
+ objectClass.setReifiedClass(RubyObject.class);
objectClass.defineAnnotatedMethods(ObjectMethods.class);
@@ -1251,7 +1252,7 @@ public IRubyObject to_s() {
*
* The default to_a method is deprecated.
*/
- @JRubyMethod(name = "to_a", visibility = Visibility.PUBLIC)
+ @JRubyMethod(name = "to_a", visibility = Visibility.PUBLIC, compat = CompatVersion.RUBY1_8)
public RubyArray to_a() {
getRuntime().getWarnings().warn(ID.DEPRECATED_METHOD, "default 'to_a' will be obsolete", "to_a");
return getRuntime().newArray(this);
View
4 src/org/jruby/RubyProc.java
@@ -45,6 +45,7 @@
import org.jruby.parser.BlockStaticScope;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
@@ -80,6 +81,9 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
public static RubyClass createProcClass(Ruby runtime) {
RubyClass procClass = runtime.defineClass("Proc", runtime.getObject(), PROC_ALLOCATOR);
runtime.setProc(procClass);
+
+ procClass.index = ClassIndex.PROC;
+ procClass.setReifiedClass(RubyProc.class);
procClass.defineAnnotatedMethods(RubyProc.class);
View
5 src/org/jruby/RubyRange.java
@@ -52,6 +52,7 @@
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.BlockCallback;
import org.jruby.runtime.CallBlock;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ObjectMarshal;
import org.jruby.runtime.ThreadContext;
@@ -77,6 +78,10 @@
public static RubyClass createRangeClass(Ruby runtime) {
RubyClass result = runtime.defineClass("Range", runtime.getObject(), RANGE_ALLOCATOR);
runtime.setRange(result);
+
+ result.index = ClassIndex.RANGE;
+ result.setReifiedClass(RubyRange.class);
+
result.kindOf = new RubyModule.KindOf() {
public boolean isKindOf(IRubyObject obj, RubyModule type) {
return obj instanceof RubyRange;
View
2  src/org/jruby/RubyRational.java
@@ -83,6 +83,8 @@ public static RubyClass createRationalClass(Ruby runtime) {
runtime.setRational(rationalc);
rationalc.index = ClassIndex.RATIONAL;
+ rationalc.setReifiedClass(RubyRational.class);
+
rationalc.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
3  src/org/jruby/RubyRegexp.java
@@ -209,7 +209,10 @@ private static Regex getPreprocessedRegexpFromCache(Ruby runtime, ByteList bytes
public static RubyClass createRegexpClass(Ruby runtime) {
RubyClass regexpClass = runtime.defineClass("Regexp", runtime.getObject(), REGEXP_ALLOCATOR);
runtime.setRegexp(regexpClass);
+
regexpClass.index = ClassIndex.REGEXP;
+ regexpClass.setReifiedClass(RubyRegexp.class);
+
regexpClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
View
6 src/org/jruby/RubyString.java
@@ -110,6 +110,7 @@
@JRubyClass(name="String", include={"Enumerable", "Comparable"})
public class RubyString extends RubyObject implements EncodingCapable {
private static final ASCIIEncoding ASCII = ASCIIEncoding.INSTANCE;
+ private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
// string doesn't share any resources
private static final int SHARE_LEVEL_NONE = 0;
@@ -126,6 +127,7 @@ public static RubyClass createStringClass(Ruby runtime) {
RubyClass stringClass = runtime.defineClass("String", runtime.getObject(), STRING_ALLOCATOR);
runtime.setString(stringClass);
stringClass.index = ClassIndex.STRING;
+ stringClass.setReifiedClass(RubyString.class);
stringClass.kindOf = new RubyModule.KindOf() {
@Override
public boolean isKindOf(IRubyObject obj, RubyModule type) {
@@ -365,6 +367,10 @@ private boolean eql19(Ruby runtime, IRubyObject other) {
return isComparableWith(otherString) && value.equal(((RubyString)other).value);
}
+ public RubyString(Ruby runtime, RubyClass rubyClass) {
+ this(runtime, rubyClass, EMPTY_BYTE_ARRAY);
+ }
+
public RubyString(Ruby runtime, RubyClass rubyClass, CharSequence value) {
super(runtime, rubyClass);
assert value != null;
View
4 src/org/jruby/RubyStruct.java
@@ -198,7 +198,7 @@ public static RubyClass newInstance(IRubyObject recv, IRubyObject[] args, Block
RubyClass superClass = (RubyClass)recv;
if (name == null || nilName) {
- newStruct = RubyClass.newClass(runtime, superClass);
+ newStruct = RubyClass.newClass(runtime, superClass);
newStruct.setAllocator(STRUCT_INSTANCE_ALLOCATOR);
newStruct.makeMetaClass(superClass.getMetaClass());
newStruct.inherit(superClass);
@@ -217,6 +217,8 @@ public static RubyClass newInstance(IRubyObject recv, IRubyObject[] args, Block
newStruct = superClass.defineClassUnder(name, superClass, STRUCT_INSTANCE_ALLOCATOR);
}
+ // set reified class to RubyStruct, for Java subclasses to use
+ newStruct.setReifiedClass(RubyStruct.class);
newStruct.index = ClassIndex.STRUCT;
newStruct.fastSetInternalVariable("__size__", member.length());
View
1  src/org/jruby/RubySymbol.java
@@ -97,6 +97,7 @@ public static RubyClass createSymbolClass(Ruby runtime) {
runtime.setSymbol(symbolClass);
RubyClass symbolMetaClass = symbolClass.getMetaClass();
symbolClass.index = ClassIndex.SYMBOL;
+ symbolClass.setReifiedClass(RubySymbol.class);
symbolClass.kindOf = new RubyModule.KindOf() {
public boolean isKindOf(IRubyObject obj, RubyModule type) {
return obj instanceof RubySymbol;
View
4 src/org/jruby/RubyThread.java
@@ -59,6 +59,7 @@
import java.util.concurrent.ExecutionException;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectMarshal;
import org.jruby.runtime.Visibility;
import org.jruby.util.io.BlockingIO;
@@ -168,6 +169,9 @@ public static RubyClass createThreadClass(Ruby runtime) {
RubyClass threadClass = runtime.defineClass("Thread", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setThread(threadClass);
+ threadClass.index = ClassIndex.THREAD;
+ threadClass.setReifiedClass(RubyThread.class);
+
threadClass.defineAnnotatedMethods(RubyThread.class);
RubyThread rubyThread = new RubyThread(runtime, threadClass);
View
3  src/org/jruby/RubyThreadGroup.java
@@ -35,6 +35,7 @@
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.collections.WeakHashSet;
@@ -55,6 +56,8 @@
public static RubyClass createThreadGroupClass(Ruby runtime) {
RubyClass threadGroupClass = runtime.defineClass("ThreadGroup", runtime.getObject(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setThreadGroup(threadGroupClass);
+
+ threadGroupClass.index = ClassIndex.THREADGROUP;
threadGroupClass.defineAnnotatedMethods(RubyThreadGroup.class);
View
3  src/org/jruby/RubyTime.java
@@ -177,7 +177,10 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
public static RubyClass createTimeClass(Ruby runtime) {
RubyClass timeClass = runtime.defineClass("Time", runtime.getObject(), TIME_ALLOCATOR);
+
timeClass.index = ClassIndex.TIME;
+ timeClass.setReifiedClass(RubyTime.class);
+
runtime.setTime(timeClass);
timeClass.includeModule(runtime.getComparable());
View
4 src/org/jruby/RubyUnboundMethod.java
@@ -32,6 +32,7 @@
import org.jruby.anno.JRubyClass;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.runtime.Block;
+import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -71,6 +72,9 @@ public static RubyClass defineUnboundMethodClass(Ruby runtime) {
runtime.defineClass("UnboundMethod", runtime.getMethod(), ObjectAllocator.NOT_ALLOCATABLE_ALLOCATOR);
runtime.setUnboundMethod(newClass);
+ newClass.index = ClassIndex.UNBOUNDMETHOD;
+ newClass.setReifiedClass(RubyUnboundMethod.class);
+
newClass.defineAnnotatedMethods(RubyUnboundMethod.class);
return newClass;
View
120 src/org/jruby/compiler/util/BasicObjectStubGenerator.java
@@ -0,0 +1,120 @@
+/***** BEGIN LICENSE BLOCK *****
+ * Version: CPL 1.0/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Common Public
+ * License Version 1.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * Copyright (C) 2009 Charles O Nutter <headius@headius.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the CPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the CPL, the GPL or the LGPL.
+ ***** END LICENSE BLOCK *****/
+package org.jruby.compiler.util;
+
+import java.lang.reflect.Method;
+import org.jruby.BasicObjectStub;
+import org.jruby.compiler.impl.SkinnyMethodAdapter;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Opcodes;
+import static org.jruby.util.CodegenUtils.*;
+
+public class BasicObjectStubGenerator {
+ private static final Method[] BASIC_OBJECT_STUB_METHODS = BasicObjectStub.class.getDeclaredMethods();
+ public static void addBasicObjectStubsToClass(ClassVisitor cv) {
+ for (Method stub : BASIC_OBJECT_STUB_METHODS) {
+ if (stub.getName().equals("getRuntime") ||
+ stub.getName().equals("getMetaClass")) {
+ // skip these and implement appropriately for the specific case
+ continue;
+ }
+
+ // trim off IRubyObject self argument
+ Class[] signature = new Class[stub.getParameterTypes().length - 1];
+ for (int i = 0; i < signature.length; i++) {
+ signature[i] = stub.getParameterTypes()[i + 1];
+ }
+
+ SkinnyMethodAdapter method = new SkinnyMethodAdapter(
+ cv.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE, stub.getName(), sig(stub.getReturnType(), signature), null, null));
+ method.start();
+
+ // load self
+ method.aload(0);
+
+ // load arguments
+ int nextIndex = 1;
+ for (Class argType : signature) {
+ if (argType.isPrimitive()) {
+ if (argType == boolean.class ||
+ argType == byte.class ||
+ argType == char.class ||
+ argType == short.class ||
+ argType == int.class) {
+ method.iload(nextIndex);
+ nextIndex++;
+ } else if (argType == long.class) {
+ method.lload(nextIndex);
+ nextIndex += 2;
+ } else if (argType == float.class) {
+ method.fload(nextIndex);
+ nextIndex++;
+ } else if (argType == double.class) {
+ method.dload(nextIndex);
+ nextIndex += 2;
+ } else {
+ throw new RuntimeException("unknown primitive type: " + argType);
+ }
+ } else {
+ method.aload(nextIndex);
+ nextIndex++;
+ }
+ }
+
+ // invoke stub
+ method.invokestatic(p(BasicObjectStub.class), stub.getName(), sig(stub.getReturnType(), stub.getParameterTypes()));
+
+ Class retType = stub.getReturnType();
+ if (retType == void.class) {
+ method.voidreturn();
+ } else {
+ if (retType.isPrimitive()) {
+ if (retType == boolean.class ||
+ retType == byte.class ||
+ retType == char.class ||
+ retType == short.class ||
+ retType == int.class) {
+ method.ireturn();
+ } else if (retType == long.class) {
+ method.lreturn();
+ } else if (retType == float.class) {
+ method.freturn();
+ } else if (retType == double.class) {
+ method.dreturn();
+ } else {
+ throw new RuntimeException("unknown primitive type: " + retType);
+ }
+ } else {
+ method.areturn();
+ }
+ }
+
+ method.end();
+ }
+ }
+}
View
2  src/org/jruby/ext/ffi/AutoPointer.java
@@ -21,7 +21,7 @@
private static final ConcurrentMap<Reaper, Boolean> referenceSet = new ConcurrentHashMap<Reaper, Boolean>();
private Pointer pointer;
- private volatile Reaper reaper;
+ private transient volatile Reaper reaper;
public static RubyClass createAutoPointerClass(Ruby runtime, RubyModule module) {
RubyClass result = module.defineClassUnder(AUTOPTR_CLASS_NAME,
View
36 src/org/jruby/ext/ffi/CallbackInfo.java
@@ -31,6 +31,7 @@
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
+import org.jruby.RubyHash;
import org.jruby.RubyModule;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
@@ -51,6 +52,7 @@
protected final Type[] parameterTypes;
protected final Type returnType;
+ protected final boolean stdcall;
private volatile Object providerCallbackInfo;
@@ -81,11 +83,12 @@ public static RubyClass createCallbackInfoClass(Ruby runtime, RubyModule module)
* @param returnType The return type of the callback
* @param paramTypes The parameter types of the callback
*/
- public CallbackInfo(Ruby runtime, RubyClass klazz, Type returnType, Type[] paramTypes) {
+ public CallbackInfo(Ruby runtime, RubyClass klazz, Type returnType, Type[] paramTypes, boolean stdcall) {
super(runtime, klazz, NativeType.POINTER);
this.arity = Arity.fixed(paramTypes.length);
this.parameterTypes = paramTypes;
this.returnType = returnType;
+ this.stdcall = stdcall;
}
/**
@@ -98,30 +101,45 @@ public CallbackInfo(Ruby runtime, RubyClass klazz, Type returnType, Type[] param
*
* @return A new CallbackInfo instance
*/
- @JRubyMethod(name = "new", meta = true)
+ @JRubyMethod(name = "new", meta = true, required = 2, optional = 1)
public static final IRubyObject newCallbackInfo(ThreadContext context, IRubyObject klass,
- IRubyObject returnType, IRubyObject paramTypes)
+ IRubyObject[] args)
{
+ IRubyObject returnType = args[0], paramTypes = args[1];
+
if (!(returnType instanceof Type)) {
- throw context.getRuntime().newArgumentError("wrong argument type "
+ throw context.getRuntime().newTypeError("wrong argument type "
+ returnType.getMetaClass().getName() + " (expected FFI::Type)");
}
+
if (!(paramTypes instanceof RubyArray)) {
- throw context.getRuntime().newArgumentError("wrong argument type "
+ throw context.getRuntime().newTypeError("wrong argument type "
+ paramTypes.getMetaClass().getName() + " (expected Array)");
}
+
Type[] nativeParamTypes = new Type[((RubyArray)paramTypes).size()];
for (int i = 0; i < nativeParamTypes.length; ++i) {
IRubyObject obj = ((RubyArray) paramTypes).entry(i);
if (!(obj instanceof Type)) {
- throw context.getRuntime().newArgumentError("wrong argument type "
+ throw context.getRuntime().newTypeError("wrong argument type "
+ obj.getMetaClass().getName() + " (expected array of FFI::Type)");
}
nativeParamTypes[i] = (Type) obj;
}
+
+ boolean stdcall = false;
+ if (args.length > 2) {
+ if (!(args[2] instanceof RubyHash)) {
+ throw context.getRuntime().newTypeError("wrong argument type "
+ + args[3].getMetaClass().getName() + " (expected Hash)");
+ }
+ RubyHash hash = (RubyHash) args[2];
+ stdcall = "stdcall".equals(hash.get(context.getRuntime().newSymbol("convention")));
+ }
+
try {
return new CallbackInfo(context.getRuntime(), (RubyClass) klass,
- (Type) returnType, nativeParamTypes);
+ (Type) returnType, nativeParamTypes, stdcall);
} catch (UnsatisfiedLinkError ex) {
return context.getRuntime().getNil();
}
@@ -154,6 +172,10 @@ public final Type getReturnType() {
return parameterTypes;
}
+ public final boolean isStdcall() {
+ return stdcall;
+ }
+
public final Object getProviderCallbackInfo() {
return providerCallbackInfo;
}
View
2  src/org/jruby/ext/ffi/Platform.java
@@ -339,7 +339,7 @@ public static String getProperty(String property, String defValue) {
* @return the size of a long in bits
*/
public final int longSize() {
- return addressSize;
+ return longSize;
}
/**
View
2  src/org/jruby/ext/ffi/StructLayout.java
@@ -457,7 +457,7 @@ private final long getOffset(IRubyObject index) {
}
private final long getOffset(int index) {
- return offset + (index * arrayType.getComponentType().getNativeSize());
+ return offset + (long) (index * arrayType.getComponentType().getNativeSize());
}
private IRubyObject get(Ruby runtime, int index) {
View
6 src/org/jruby/ext/ffi/jffi/CallbackManager.java
@@ -147,7 +147,8 @@ private final ClosureInfo getClosureInfo(Ruby runtime, CallbackInfo cbInfo) {
}
private final ClosureInfo newClosureInfo(Ruby runtime, CallbackInfo cbInfo) {
- return new ClosureInfo(runtime, cbInfo.getReturnType(), cbInfo.getParameterTypes(), CallingConvention.DEFAULT);
+ return new ClosureInfo(runtime, cbInfo.getReturnType(), cbInfo.getParameterTypes(),
+ cbInfo.isStdcall() ? CallingConvention.STDCALL : CallingConvention.DEFAULT);
}
/**
@@ -476,7 +477,8 @@ private static final IRubyObject fromNative(Ruby runtime, Type type,
CallbackInfo cbInfo = (CallbackInfo) type;
if (address != 0) {
return new JFFIInvoker(runtime, address,
- cbInfo.getReturnType(), cbInfo.getParameterTypes());
+ cbInfo.getReturnType(), cbInfo.getParameterTypes(),
+ cbInfo.isStdcall() ? CallingConvention.STDCALL : CallingConvention.DEFAULT);
} else {
return runtime.getNil();
}
View
4 src/org/jruby/ext/ffi/jffi/DefaultMethodFactory.java
@@ -489,10 +489,12 @@ public final IRubyObject invoke(ThreadContext context, Function function, HeapIn
private static final class CallbackInvoker extends BaseInvoker {
private final Type returnType;
private final Type[] parameterTypes;
+ private final CallingConvention convention;
public CallbackInvoker(CallbackInfo cbInfo) {
this.returnType = cbInfo.getReturnType();
this.parameterTypes = cbInfo.getParameterTypes();
+ this.convention = cbInfo.isStdcall() ? CallingConvention.STDCALL : CallingConvention.DEFAULT;
}
@@ -501,7 +503,7 @@ public final IRubyObject invoke(ThreadContext context, Function function, HeapIn
if (address == 0) {
return context.getRuntime().getNil();
}
- return new JFFIInvoker(context.getRuntime(), address, returnType, parameterTypes);
+ return new JFFIInvoker(context.getRuntime(), address, returnType, parameterTypes, convention);
}
}
View
3  src/org/jruby/ext/ffi/jffi/FFIUtil.java
@@ -10,6 +10,7 @@
import org.jruby.RubyString;
import org.jruby.ext.ffi.CallbackInfo;
import org.jruby.ext.ffi.NativeType;
+import org.jruby.ext.ffi.Platform;
import org.jruby.ext.ffi.StructLayout;
import org.jruby.ext.ffi.Type;
import org.jruby.runtime.ThreadContext;
@@ -38,7 +39,7 @@ private FFIUtil() {}
m.put(NativeType.UINT, com.kenai.jffi.Type.UINT32);
m.put(NativeType.ULONG_LONG, com.kenai.jffi.Type.UINT64);
- if (com.kenai.jffi.Platform.getPlatform().longSize() == 32) {
+ if (Platform.getPlatform().longSize() == 32) {
m.put(NativeType.LONG, com.kenai.jffi.Type.SINT32);
m.put(NativeType.ULONG, com.kenai.jffi.Type.UINT32);
} else {
View
3  src/org/jruby/ext/ffi/jffi/Factory.java
@@ -82,7 +82,8 @@ public Function newFunction(Ruby runtime, Pointer address, CallbackInfo cbInfo)
CodeMemoryIO mem = new CodeMemoryIO(runtime, address);
RubyClass klass = runtime.fastGetModule("FFI").fastGetClass("Function");
return new Function(runtime, klass, mem,
- cbInfo.getReturnType(), cbInfo.getParameterTypes(), CallingConvention.DEFAULT, null);
+ cbInfo.getReturnType(), cbInfo.getParameterTypes(),
+ cbInfo.isStdcall() ? CallingConvention.STDCALL : CallingConvention.DEFAULT, null);
}
View
20 src/org/jruby/ext/ffi/jffi/JFFIInvoker.java
@@ -14,7 +14,6 @@
import org.jruby.ext.ffi.Pointer;
import org.jruby.ext.ffi.Type;
import org.jruby.internal.runtime.methods.DynamicMethod;
-import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -36,16 +35,15 @@ public static RubyClass createInvokerClass(Ruby runtime, RubyModule module) {
return result;
}
-
-
- JFFIInvoker(Ruby runtime, long address, Type returnType, Type[] parameterTypes) {
+
+ JFFIInvoker(Ruby runtime, long address, Type returnType, Type[] parameterTypes, CallingConvention convention) {
this(runtime, runtime.fastGetModule("FFI").fastGetClass("Invoker"),
new CodeMemoryIO(runtime, address),
- returnType, parameterTypes, "default", null);
+ returnType, parameterTypes, convention, null);
}
JFFIInvoker(Ruby runtime, RubyClass klass, DirectMemoryIO fptr,
- Type returnType, Type[] parameterTypes, String convention, IRubyObject enums) {
+ Type returnType, Type[] parameterTypes, CallingConvention convention, IRubyObject enums) {
super(runtime, klass, parameterTypes.length, fptr);
final com.kenai.jffi.Type jffiReturnType = FFIUtil.getFFIType(returnType);
@@ -61,11 +59,9 @@ public static RubyClass createInvokerClass(Ruby runtime, RubyModule module) {
}
function = new Function(fptr.getAddress(), jffiReturnType, jffiParamTypes);
- this.parameterTypes = new Type[parameterTypes.length];
- System.arraycopy(parameterTypes, 0, this.parameterTypes, 0, parameterTypes.length);
+ this.parameterTypes = (Type[]) parameterTypes.clone();
this.returnType = returnType;
- this.convention = "stdcall".equals(convention)
- ? CallingConvention.STDCALL : CallingConvention.DEFAULT;
+ this.convention = convention;
this.enums = enums;
// Wire up Function#call(*args) to use the super-fast native invokers
getSingletonClass().addMethod("call", createDynamicMethod(getSingletonClass()));
@@ -117,7 +113,9 @@ public static IRubyObject newInstance(ThreadContext context, IRubyObject recv, I
}
DirectMemoryIO fptr = (DirectMemoryIO) ptr.getMemoryIO();
return new JFFIInvoker(context.getRuntime(), (RubyClass) recv, fptr,
- (Type) returnType, parameterTypes, convention, enums);
+ (Type) returnType, parameterTypes,
+ "stdcall".equals(convention) ? CallingConvention.STDCALL : CallingConvention.DEFAULT,
+ enums);
}
@Override
View
2  src/org/jruby/ext/ffi/jffi/VariadicInvoker.java
@@ -63,7 +63,7 @@ public final Arity getArity() {
@JRubyMethod(name = { "__new" }, meta = true, required = 4)
public static VariadicInvoker newInvoker(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
CallingConvention conv = "stdcall".equals(args[3].toString())
- ? CallingConvention.STDCALL : CallingConvention.STDCALL;
+ ? CallingConvention.STDCALL : CallingConvention.DEFAULT;
Library library;
long address;
try {
View
413 src/org/jruby/java/MiniJava.java
@@ -19,12 +19,14 @@
import java.util.Map;
import java.util.Set;
import org.jruby.Ruby;
+import org.jruby.RubyBasicObject;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.anno.JRubyMethod;
import org.jruby.compiler.impl.SkinnyMethodAdapter;
+import org.jruby.compiler.util.BasicObjectStubGenerator;
import org.jruby.compiler.util.HandleFactory;
import org.jruby.compiler.util.HandleFactory.Handle;
import org.jruby.exceptions.RaiseException;
@@ -52,6 +54,21 @@
*/
public class MiniJava implements Library {
private static final boolean DEBUG = false;
+
+ private static Map<String, List<Method>> buildSimpleToAllMap(Class[] interfaces, String[] superTypeNames) throws SecurityException {
+ Map<String, List<Method>> simpleToAll = new HashMap<String, List<Method>>();
+ for (int i = 0; i < interfaces.length; i++) {
+ superTypeNames[i] = p(interfaces[i]);
+ for (Method method : interfaces[i].getMethods()) {
+ List<Method> methods = simpleToAll.get(method.getName());
+ if (methods == null) {
+ simpleToAll.put(method.getName(), methods = new ArrayList<Method>());
+ }
+ methods.add(method);
+ }
+ }
+ return simpleToAll;
+ }
public void load(Ruby runtime, boolean wrap) {
runtime.getErr().print("Warning: minijava is experimental and subject to change\n");
@@ -161,16 +178,7 @@ public static IRubyObject rb_import(ThreadContext context, IRubyObject self, IRu
public static RubyClass createImplClass(Class[] superTypes, Ruby ruby, String name) {
String[] superTypeNames = new String[superTypes.length];
- Map<String, List<Method>> simpleToAll = new HashMap<String, List<Method>>();
- for (int i = 0; i < superTypes.length; i++) {
- superTypeNames[i] = p(superTypes[i]);
-
- for (Method method : superTypes[i].getMethods()) {
- List<Method> methods = simpleToAll.get(method.getName());
- if (methods == null) simpleToAll.put(method.getName(), methods = new ArrayList<Method>());
- methods.add(method);
- }
- }
+ Map<String, List<Method>> simpleToAll = buildSimpleToAllMap(superTypes, superTypeNames);
Class newClass = defineImplClass(ruby, name, superTypeNames, simpleToAll);
RubyClass rubyCls = populateImplClass(ruby, newClass, simpleToAll);
@@ -180,21 +188,21 @@ public static RubyClass createImplClass(Class[] superTypes, Ruby ruby, String na
public static Class createOldStyleImplClass(Class[] superTypes, RubyClass rubyClass, Ruby ruby, String name) {
String[] superTypeNames = new String[superTypes.length];
- Map<String, List<Method>> simpleToAll = new HashMap<String, List<Method>>();
- for (int i = 0; i < superTypes.length; i++) {
- superTypeNames[i] = p(superTypes[i]);
-
- for (Method method : superTypes[i].getMethods()) {
- List<Method> methods = simpleToAll.get(method.getName());
- if (methods == null) simpleToAll.put(method.getName(), methods = new ArrayList<Method>());
- methods.add(method);
- }
- }
+ Map<String, List<Method>> simpleToAll = buildSimpleToAllMap(superTypes, superTypeNames);
Class newClass = defineOldStyleImplClass(ruby, name, superTypeNames, simpleToAll);
return newClass;
}
+
+ public static Class createRealImplClass(Class superClass, Class[] interfaces, RubyClass rubyClass, Ruby ruby, String name) {
+ String[] superTypeNames = new String[interfaces.length];
+ Map<String, List<Method>> simpleToAll = buildSimpleToAllMap(interfaces, superTypeNames);
+
+ Class newClass = defineRealImplClass(ruby, name, superClass, superTypeNames, simpleToAll);
+
+ return newClass;
+ }
public static Class defineImplClass(Ruby ruby, String name, String[] superTypeNames, Map<String, List<Method>> simpleToAll) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
@@ -592,6 +600,295 @@ public static Class defineOldStyleImplClass(Ruby ruby, String name, String[] sup
return newClass;
}
+ /**
+ * This variation on defineImplClass uses all the classic type coercion logic
+ * for passing args and returning results.
+ *
+ * @param ruby
+ * @param name
+ * @param superTypeNames