Skip to content

Commit

Permalink
Merge branch 'jruby-1_5' of jruby.org:jruby into jruby-1_5
Browse files Browse the repository at this point in the history
  • Loading branch information
nicksieger committed Dec 2, 2010
2 parents 2831f2d + 8d69a1e commit 9cf97c3
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 26 deletions.
2 changes: 1 addition & 1 deletion default.build.properties
Expand Up @@ -63,6 +63,6 @@ version.ruby.patchlevel=249
version.ruby1_9.major=1.9
version.ruby1_9=1.9.2dev
version.ruby1_9.patchlevel=24787
version.jruby=1.5.5
version.jruby=1.5.6
mspec.revision=26e25432f613856640a591fe098bec5ed80f40a1
rubyspecs.revision=b8d81ce02208d1f4fbc939d002dccc55bca285f6
4 changes: 2 additions & 2 deletions maven/jruby-complete/pom.xml
Expand Up @@ -4,14 +4,14 @@
<parent>
<groupId>org.jruby</groupId>
<artifactId>shared</artifactId>
<version>1.5.5</version>
<version>1.5.6</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<packaging>jar</packaging>
<version>1.5.5</version>
<version>1.5.6</version>
<name>JRuby Complete</name>

<dependencies>
Expand Down
6 changes: 3 additions & 3 deletions maven/jruby-rake-plugin/pom.xml
Expand Up @@ -3,14 +3,14 @@
<parent>
<groupId>org.jruby</groupId>
<artifactId>shared</artifactId>
<version>1.5.5</version>
<version>1.5.6</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jruby.plugins</groupId>
<artifactId>jruby-rake-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.5.5</version>
<version>1.5.6</version>
<name>JRuby Rake Plugin</name>
<dependencies>
<dependency>
Expand All @@ -31,7 +31,7 @@
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby-complete</artifactId>
<version>1.5.5</version>
<version>1.5.6</version>
</dependency>
</dependencies>

Expand Down
4 changes: 2 additions & 2 deletions maven/jruby/pom.xml
Expand Up @@ -4,14 +4,14 @@
<parent>
<groupId>org.jruby</groupId>
<artifactId>shared</artifactId>
<version>1.5.5</version>
<version>1.5.6</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jruby</groupId>
<artifactId>jruby</artifactId>
<packaging>jar</packaging>
<version>1.5.5</version>
<version>1.5.6</version>
<name>JRuby</name>

<properties>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -5,7 +5,7 @@
<groupId>org.jruby</groupId>
<artifactId>shared</artifactId>
<packaging>pom</packaging>
<version>1.5.5</version>
<version>1.5.6</version>
<name>JRuby Shared</name>
<url>http://www.jruby.org/</url>
<description>A 1.8.7 compatible Ruby interpreter written in 100% pure Java</description>
Expand Down
Expand Up @@ -35,4 +35,20 @@ class ReifyInterfacesClass2
ReifyInterfacesClass1::ReifyInterfacesClass2.new
end.should_not raise_error
end

it "creates static methods for Ruby class methods" do
cls = Class.new do
class << self
def blah
end
end
end

java_class = cls.become_java!

method = java_class.declared_methods.select {|m| m.name == "blah"}[0]
method.name.should == "blah"
method.return_type.should == org.jruby.runtime.builtin.IRubyObject.java_class
method.parameter_types.length.should == 0
end
end
82 changes: 75 additions & 7 deletions src/org/jruby/RubyClass.java
Expand Up @@ -30,6 +30,15 @@
***** END LICENSE BLOCK *****/
package org.jruby;

import static org.jruby.util.CodegenUtils.ci;
import static org.jruby.util.CodegenUtils.p;
import static org.jruby.util.CodegenUtils.sig;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.ACC_SUPER;
import static org.objectweb.asm.Opcodes.ACC_VARARGS;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
Expand All @@ -43,12 +52,10 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyClass;

import org.jruby.exceptions.RaiseException;
import org.jruby.anno.JRubyMethod;
import org.jruby.compiler.impl.SkinnyMethodAdapter;
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.java.codegen.RealClassGenerator;
Expand All @@ -68,15 +75,12 @@
import org.jruby.runtime.marshal.UnmarshalStream;
import org.jruby.util.CodegenUtils;
import org.jruby.util.JRubyClassLoader;
import static org.jruby.util.CodegenUtils.*;
import org.jruby.util.JavaNameMangler;
import org.jruby.util.collections.WeakHashSet;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;

import static org.objectweb.asm.Opcodes.*;

/**
*
* @author jpetersen
Expand Down Expand Up @@ -1271,6 +1275,70 @@ public synchronized void reify(String classDumpDir) {

m.end();
}

for (Map.Entry<String,DynamicMethod> methodEntry : getMetaClass().getMethods().entrySet()) {
String methodName = methodEntry.getKey();
String javaMethodName = JavaNameMangler.mangleStringForCleanJavaIdentifier(methodName);
Map<Class,Map<String,Object>> methodAnnos = getMetaClass().getMethodAnnotations().get(methodName);
List<Map<Class,Map<String,Object>>> parameterAnnos = getMetaClass().getParameterAnnotations().get(methodName);
Class[] methodSignature = getMetaClass().getMethodSignatures().get(methodName);

if (methodSignature == null) {
// non-signature signature with just IRubyObject
switch (methodEntry.getValue().getArity().getValue()) {
case 0:
m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, sig(IRubyObject.class), null, null);
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
//m.invokevirtual("org/jruby/RubyClass", "getMetaClass", sig(RubyClass.class) );
m.ldc(methodName); // Method name
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class) );
break;
default:
m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, sig(IRubyObject.class, IRubyObject[].class), null, null);
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));
m.ldc(methodName); // Method name
m.aload(0);
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class) );
}
m.areturn();
} else {
// generate a real method signature for the method, with to/from coercions

// indices for temp values
Class[] params = new Class[methodSignature.length - 1];
System.arraycopy(methodSignature, 1, params, 0, params.length);
int baseIndex = 1;
for (Class paramType : params) {
if (paramType == double.class || paramType == long.class) {
baseIndex += 2;
} else {
baseIndex += 1;
}
}
int rubyIndex = baseIndex;

m = new SkinnyMethodAdapter(cw, ACC_PUBLIC | ACC_VARARGS | ACC_STATIC, javaMethodName, sig(methodSignature[0], params), null, null);
generateMethodAnnotations(methodAnnos, m, parameterAnnos);

m.getstatic(javaPath, "ruby", ci(Ruby.class));
m.astore(rubyIndex);

m.getstatic(javaPath, "rubyClass", ci(RubyClass.class));

m.ldc(methodName); // method name
RealClassGenerator.coerceArgumentsToRuby(m, params, rubyIndex);
m.invokevirtual("org/jruby/RubyClass", "callMethod", sig(IRubyObject.class, String.class, IRubyObject[].class));

RealClassGenerator.coerceResultAndReturn(m, methodSignature[0]);
}

m.end();
}


cw.visitEnd();
byte[] classBytes = cw.toByteArray();
Expand Down
18 changes: 11 additions & 7 deletions src/org/jruby/RubyMarshal.java
Expand Up @@ -148,18 +148,22 @@ public static IRubyObject load(ThreadContext context, IRubyObject recv, IRubyObj

InputStream rawInput;
boolean tainted = false;
if (in != null && in.respondsTo("read")) {
IRubyObject v = in.checkStringType();
if (!v.isNil()) {
tainted = in.isTaint();
ByteList bytes = ((RubyString) v).getByteList();
rawInput = new ByteArrayInputStream(bytes.getUnsafeBytes(), bytes.begin(),
bytes.length());
} else if (in.respondsTo("getc") && in.respondsTo("read")) {
if (in.respondsTo("binmode")) {
RuntimeHelpers.invoke(context, in, "binmode");
}
tainted = true;
rawInput = inputStream(in);
} else if (in != null && in.respondsTo("to_str")) {
tainted = in.isTaint();
RubyString inString = (RubyString) RuntimeHelpers.invoke(context, in, "to_str");
ByteList bytes = inString.getByteList();
rawInput = new ByteArrayInputStream(bytes.getUnsafeBytes(), bytes.begin(), bytes.length());
} else {
throw recv.getRuntime().newTypeError("instance of IO needed");
}

UnmarshalStream input = new UnmarshalStream(recv.getRuntime(), rawInput, proc, tainted);

return input.unmarshalObject();
Expand Down
11 changes: 11 additions & 0 deletions src/org/jruby/compiler/impl/SkinnyMethodAdapter.java
Expand Up @@ -17,6 +17,9 @@

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
Expand All @@ -29,11 +32,19 @@
public class SkinnyMethodAdapter implements MethodVisitor, Opcodes {
private final static boolean DEBUG = SafePropertyAccessor.getBoolean("jruby.compile.dump");
private MethodVisitor method;
private String name;
private ClassVisitor cv;

/** Creates a new instance of SkinnyMethodAdapter */
public SkinnyMethodAdapter(MethodVisitor method) {
setMethodVisitor(method);
}

public SkinnyMethodAdapter(ClassVisitor cv, int flags, String name, String signature, String something, String[] exceptions) {
setMethodVisitor(cv.visitMethod(flags, name, signature, something, exceptions));
this.cv = cv;
this.name = name;
}

public SkinnyMethodAdapter() {
}
Expand Down
3 changes: 2 additions & 1 deletion src/org/jruby/java/proxies/JavaProxy.java
Expand Up @@ -37,6 +37,7 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.CodegenUtils;
import org.jruby.util.JRubyObjectInputStream;

public class JavaProxy extends RubyObject {
private static final boolean DEBUG = false;
Expand Down Expand Up @@ -369,7 +370,7 @@ public IRubyObject marshal_load(ThreadContext context, IRubyObject str) {
try {
ByteList byteList = str.convertToString().getByteList();
ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
ObjectInputStream ois = new ObjectInputStream(bais);
ObjectInputStream ois = new JRubyObjectInputStream(context.getRuntime(), bais);

object = ois.readObject();

Expand Down
3 changes: 2 additions & 1 deletion src/org/jruby/javasupport/JavaObject.java
Expand Up @@ -53,6 +53,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.JRubyObjectInputStream;

/**
*
Expand Down Expand Up @@ -309,7 +310,7 @@ public IRubyObject marshal_load(ThreadContext context, IRubyObject str) {
try {
ByteList byteList = str.convertToString().getByteList();
ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
ObjectInputStream ois = new ObjectInputStream(bais);
ObjectInputStream ois = new JRubyObjectInputStream(context.getRuntime(), bais);

dataWrapStruct(ois.readObject());

Expand Down
2 changes: 1 addition & 1 deletion src/org/jruby/libraries/RbConfigLibrary.java
Expand Up @@ -78,7 +78,7 @@ public class RbConfigLibrary implements Library {
RUBY_OS_NAMES.put("Windows 2003", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows Vista", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 7", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows 2008 Server", RUBY_WIN32);
RUBY_OS_NAMES.put("Windows Server 2008", RUBY_WIN32);
RUBY_OS_NAMES.put("Solaris", RUBY_SOLARIS);
RUBY_OS_NAMES.put("FreeBSD", RUBY_FREEBSD);
RUBY_OS_NAMES.put("AIX", RUBY_AIX);
Expand Down
27 changes: 27 additions & 0 deletions src/org/jruby/util/JRubyObjectInputStream.java
@@ -0,0 +1,27 @@
package org.jruby.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import org.jruby.Ruby;

public class JRubyObjectInputStream extends ObjectInputStream {
private final Ruby runtime;

public JRubyObjectInputStream(Ruby runtime, InputStream input) throws IOException {
super(input);
this.runtime = runtime;
}

protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String name = desc.getName();
try {
return Class.forName(name, false, runtime.getJRubyClassLoader());
} catch (ClassNotFoundException ex) {
return super.resolveClass(desc);
}
}
}

0 comments on commit 9cf97c3

Please sign in to comment.