Skip to content

Commit

Permalink
[Truffle] Remove RubyMethod class.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed May 29, 2015
1 parent 18e602d commit ba06032
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 74 deletions.
Expand Up @@ -11,6 +11,7 @@

import com.oracle.truffle.api.interop.TruffleObject;
import org.jruby.truffle.nodes.core.BigDecimalNodes;
import org.jruby.truffle.nodes.core.MethodNodes;
import org.jruby.truffle.runtime.ThreadLocalObject;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;
Expand Down Expand Up @@ -86,7 +87,11 @@ public static boolean isRubySymbol(Object value) {
}

public static boolean isRubyMethod(Object value) {
return value instanceof RubyMethod;
return (value instanceof RubyBasicObject) && isRubyMethod((RubyBasicObject) value);
}

public static boolean isRubyMethod(RubyBasicObject value) {
return value.getDynamicObject().getShape().getObjectType() == MethodNodes.METHOD_TYPE;
}

public static boolean isRubyUnboundMethod(Object value) {
Expand Down
Expand Up @@ -1043,16 +1043,16 @@ public MethodNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubyMethod method(Object object, RubySymbol name) {
public RubyBasicObject method(Object object, RubySymbol name) {
return method(object, name.toString());
}

@Specialization
public RubyMethod method(Object object, RubyString name) {
public RubyBasicObject method(Object object, RubyString name) {
return method(object, name.toString());
}

private RubyMethod method(Object object, String name) {
private RubyBasicObject method(Object object, String name) {
CompilerDirectives.transferToInterpreter();

// TODO(CS, 11-Jan-15) cache this lookup
Expand All @@ -1065,7 +1065,7 @@ private RubyMethod method(Object object, String name) {
name, getContext().getCoreLibrary().getLogicalClass(object), this));
}

return new RubyMethod(getContext().getCoreLibrary().getMethodClass(), object, method);
return MethodNodes.createMethod(getContext().getCoreLibrary().getMethodClass(), object, method);
}

}
Expand Down
111 changes: 79 additions & 32 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/MethodNodes.java
Expand Up @@ -15,6 +15,7 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.IndirectCallNode;
import com.oracle.truffle.api.object.*;
import com.oracle.truffle.api.source.NullSourceSection;
import com.oracle.truffle.api.source.SourceSection;

Expand All @@ -29,10 +30,54 @@
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.object.BasicObjectType;

import java.util.EnumSet;

@CoreClass(name = "Method")
public abstract class MethodNodes {

public static class MethodType extends BasicObjectType {

}

public static final MethodType METHOD_TYPE = new MethodType();

private static final HiddenKey RECEIVER_IDENTIFIER = new HiddenKey("receiver");
public static final Property RECEIVER_PROPERTY;

private static final HiddenKey METHOD_IDENTIFIER = new HiddenKey("method");
public static final Property METHOD_PROPERTY;

private static final DynamicObjectFactory METHOD_FACTORY;

static {
final Shape.Allocator allocator = RubyBasicObject.LAYOUT.createAllocator();

RECEIVER_PROPERTY = Property.create(RECEIVER_IDENTIFIER, allocator.locationForType(Object.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);
METHOD_PROPERTY = Property.create(METHOD_IDENTIFIER, allocator.locationForType(InternalMethod.class, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull)), 0);

final Shape shape = RubyBasicObject.LAYOUT.createShape(METHOD_TYPE)
.addProperty(RECEIVER_PROPERTY)
.addProperty(METHOD_PROPERTY);

METHOD_FACTORY = shape.createFactory();
}

public static RubyBasicObject createMethod(RubyClass rubyClass, Object receiver, InternalMethod method) {
return new RubyBasicObject(rubyClass, METHOD_FACTORY.newInstance(receiver, method));
}

public static Object getReceiver(RubyBasicObject method) {
assert method.getDynamicObject().getShape().hasProperty(RECEIVER_IDENTIFIER);
return RECEIVER_PROPERTY.get(method.getDynamicObject(), true);
}

public static InternalMethod getMethod(RubyBasicObject method) {
assert method.getDynamicObject().getShape().hasProperty(METHOD_IDENTIFIER);
return (InternalMethod) METHOD_PROPERTY.get(method.getDynamicObject(), true);
}

@CoreMethod(names = { "==", "eql?" }, required = 1)
public abstract static class EqualNode extends CoreMethodArrayArgumentsNode {

Expand All @@ -50,13 +95,13 @@ protected boolean areSame(VirtualFrame frame, Object left, Object right) {
return referenceEqualNode.executeReferenceEqual(frame, left, right);
}

@Specialization
public boolean equal(VirtualFrame frame, RubyMethod a, RubyMethod b) {
return areSame(frame, a.getReceiver(), b.getReceiver()) && a.getMethod() == b.getMethod();
@Specialization(guards = "isRubyMethod(b)")
public boolean equal(VirtualFrame frame, RubyBasicObject a, RubyBasicObject b) {
return areSame(frame, getReceiver(a), getReceiver(b)) && getMethod(a) == getMethod(b);
}

@Specialization(guards = "!isRubyMethod(b)")
public boolean equal(RubyMethod a, Object b) {
public boolean equal(RubyBasicObject a, Object b) {
return false;
}

Expand All @@ -70,8 +115,8 @@ public ArityNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public int arity(RubyMethod method) {
return method.getMethod().getSharedMethodInfo().getArity().getArityNumber();
public int arity(RubyBasicObject method) {
return getMethod(method).getSharedMethodInfo().getArity().getArityNumber();
}

}
Expand All @@ -87,21 +132,21 @@ public CallNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object call(VirtualFrame frame, RubyMethod method, Object[] arguments, UndefinedPlaceholder block) {
public Object call(VirtualFrame frame, RubyBasicObject method, Object[] arguments, UndefinedPlaceholder block) {
return doCall(frame, method, arguments, null);
}

@Specialization
public Object doCall(VirtualFrame frame, RubyMethod method, Object[] arguments, RubyProc block) {
public Object doCall(VirtualFrame frame, RubyBasicObject method, Object[] arguments, RubyProc block) {
// TODO(CS 11-Jan-15) should use a cache and DirectCallNode here so that we can inline - but it's
// incompatible with our current dispatch chain.

final InternalMethod internalMethod = method.getMethod();
final InternalMethod internalMethod = getMethod(method);

return callNode.call(frame, method.getMethod().getCallTarget(), RubyArguments.pack(
return callNode.call(frame, getMethod(method).getCallTarget(), RubyArguments.pack(
internalMethod,
internalMethod.getDeclarationFrame(),
method.getReceiver(),
getReceiver(method),
block,
arguments));
}
Expand All @@ -116,10 +161,10 @@ public NameNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubySymbol name(RubyMethod method) {
public RubySymbol name(RubyBasicObject method) {
CompilerDirectives.transferToInterpreter();

return getContext().getSymbol(method.getMethod().getName());
return getContext().getSymbol(getMethod(method).getName());
}

}
Expand All @@ -132,8 +177,8 @@ public OwnerNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubyModule owner(RubyMethod method) {
return method.getMethod().getDeclaringModule();
public RubyModule owner(RubyBasicObject method) {
return getMethod(method).getDeclaringModule();
}

}
Expand All @@ -147,8 +192,8 @@ public ParametersNode(RubyContext context, SourceSection sourceSection) {

@TruffleBoundary
@Specialization
public RubyArray parameters(RubyMethod method) {
final ArgsNode argsNode = method.getMethod().getSharedMethodInfo().getParseTree().findFirstChild(ArgsNode.class);
public RubyArray parameters(RubyBasicObject method) {
final ArgsNode argsNode = getMethod(method).getSharedMethodInfo().getParseTree().findFirstChild(ArgsNode.class);

final ArgumentDescriptor[] argsDesc = Helpers.argsNodeToArgumentDescriptors(argsNode);

Expand All @@ -166,8 +211,8 @@ public ReceiverNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object receiver(RubyMethod method) {
return method.getReceiver();
public Object receiver(RubyBasicObject method) {
return getReceiver(method);
}

}
Expand All @@ -180,10 +225,10 @@ public SourceLocationNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public Object sourceLocation(RubyMethod method) {
public Object sourceLocation(RubyBasicObject method) {
CompilerDirectives.transferToInterpreter();

SourceSection sourceSection = method.getMethod().getSharedMethodInfo().getSourceSection();
SourceSection sourceSection = getMethod(method).getSharedMethodInfo().getSourceSection();

if (sourceSection instanceof NullSourceSection) {
return nil();
Expand All @@ -207,11 +252,11 @@ public UnbindNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubyUnboundMethod unbind(VirtualFrame frame, RubyMethod method) {
public RubyUnboundMethod unbind(VirtualFrame frame, RubyBasicObject method) {
CompilerDirectives.transferToInterpreter();

RubyClass receiverClass = classNode.executeGetClass(frame, method.getReceiver());
return new RubyUnboundMethod(getContext().getCoreLibrary().getUnboundMethodClass(), receiverClass, method.getMethod());
RubyClass receiverClass = classNode.executeGetClass(frame, getReceiver(method));
return new RubyUnboundMethod(getContext().getCoreLibrary().getUnboundMethodClass(), receiverClass, getMethod(method));
}

}
Expand All @@ -224,17 +269,19 @@ public ToProcNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization
public RubyProc toProc(RubyMethod method) {
public RubyProc toProc(RubyBasicObject methodObject) {
final InternalMethod method = getMethod(methodObject);

return new RubyProc(
getContext().getCoreLibrary().getProcClass(),
RubyProc.Type.LAMBDA,
method.getMethod().getSharedMethodInfo(),
method.getMethod().getCallTarget(),
method.getMethod().getCallTarget(),
method.getMethod().getCallTarget(),
method.getMethod().getDeclarationFrame(),
method.getMethod(),
method.getReceiver(),
method.getSharedMethodInfo(),
method.getCallTarget(),
method.getCallTarget(),
method.getCallTarget(),
method.getDeclarationFrame(),
method,
getReceiver(methodObject),
null);
}

Expand Down
Expand Up @@ -1014,9 +1014,9 @@ public RubySymbol defineMethod(RubyModule module, String name, RubyProc proc, Un
}

@TruffleBoundary
@Specialization
public RubySymbol defineMethod(RubyModule module, String name, RubyMethod method, UndefinedPlaceholder block) {
module.addMethod(this, method.getMethod().withName(name));
@Specialization(guards = "isRubyMethod(method)")
public RubySymbol defineMethod(RubyModule module, String name, RubyBasicObject method, UndefinedPlaceholder block) {
module.addMethod(this, MethodNodes.getMethod(method).withName(name));
return getContext().getSymbolTable().getSymbol(name);
}

Expand Down
Expand Up @@ -81,7 +81,7 @@ private RubyClass metaClass(VirtualFrame frame, Object object) {
}

@Specialization
public RubyMethod bind(VirtualFrame frame, RubyUnboundMethod unboundMethod, Object object) {
public RubyBasicObject bind(VirtualFrame frame, RubyUnboundMethod unboundMethod, Object object) {
CompilerDirectives.transferToInterpreter();

RubyModule module = unboundMethod.getMethod().getDeclaringModule();
Expand All @@ -95,7 +95,7 @@ public RubyMethod bind(VirtualFrame frame, RubyUnboundMethod unboundMethod, Obje
}
}

return new RubyMethod(getContext().getCoreLibrary().getMethodClass(), object, unboundMethod.getMethod());
return MethodNodes.createMethod(getContext().getCoreLibrary().getMethodClass(), object, unboundMethod.getMethod());
}

}
Expand Down

This file was deleted.

0 comments on commit ba06032

Please sign in to comment.