Skip to content

Commit

Permalink
Showing 6 changed files with 207 additions and 184 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.cast;

import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyBasicObject;

/**
* Casts a value into a boolean and defaults to the given value if not provided.
*/
@NodeChild(value = "value", type = RubyNode.class)
public abstract class BooleanCastWithDefaultNode extends RubyNode {

private final boolean defaultValue;

public BooleanCastWithDefaultNode(RubyContext context, SourceSection sourceSection, boolean defaultValue) {
super(context, sourceSection);
this.defaultValue = defaultValue;
}

public abstract boolean executeBoolean(VirtualFrame frame, Object value);

@Specialization
public boolean doDefault(NotProvided value) {
return defaultValue;
}

@Specialization
public boolean doBoolean(boolean value) {
return value;
}

@Specialization(guards = "isNil(nil)")
public boolean doNil(Object nil) {
return false;
}

@Specialization
public boolean doIntegerFixnum(int value) {
return true;
}

@Specialization
public boolean doLongFixnum(long value) {
return true;
}

@Specialization
public boolean doFloat(double value) {
return true;
}

@Specialization(guards = "!isNil(object)")
public boolean doBasicObject(RubyBasicObject object) {
return true;
}

@Override
public abstract boolean executeBoolean(VirtualFrame frame);

}
196 changes: 75 additions & 121 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.cast.BooleanCastWithDefaultNodeGen;
import org.jruby.truffle.nodes.cast.NumericToFloatNode;
import org.jruby.truffle.nodes.cast.NumericToFloatNodeGen;
import org.jruby.truffle.nodes.coerce.ToStrNodeGen;
@@ -1097,46 +1098,43 @@ private RubyBasicObject method(Object object, String name) {
}

@CoreMethod(names = "methods", optional = 1)
public abstract static class MethodsNode extends CoreMethodArrayArgumentsNode {

@Child private MetaClassNode metaClassNode;
@Child private SingletonMethodsNode singletonMethodsNode;
@Child private BooleanCastNode booleanCastNode;
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "regular")
})
public abstract static class MethodsNode extends CoreMethodNode {

public MethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.metaClassNode = MetaClassNodeGen.create(context, sourceSection, null);
}

@Specialization
public RubyBasicObject methods(VirtualFrame frame, Object self, NotProvided regular) {
return methods(frame, self, true);
@CreateCast("regular")
public RubyNode coerceToBoolean(RubyNode regular) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, regular);
}

@Specialization
public RubyBasicObject methods(VirtualFrame frame, Object self, boolean regular) {
RubyClass metaClass = metaClassNode.executeMetaClass(frame, self);
@Specialization(guards = "regular")
public RubyBasicObject methodsRegular(VirtualFrame frame, Object self, boolean regular,
@Cached("createMetaClassNode()") MetaClassNode metaClassNode) {
final RubyClass metaClass = metaClassNode.executeMetaClass(frame, self);

CompilerDirectives.transferToInterpreter();
if (regular) {
return ArrayNodes.fromObjects(getContext().getCoreLibrary().getArrayClass(),
metaClass.filterMethodsOnObject(regular, MethodFilter.PUBLIC_PROTECTED).toArray());
} else {
if (singletonMethodsNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
singletonMethodsNode = insert(SingletonMethodsNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null }));
}
return singletonMethodsNode.executeSingletonMethods(frame, self, false);
}
return ArrayNodes.fromObjects(getContext().getCoreLibrary().getArrayClass(),
metaClass.filterMethodsOnObject(regular, MethodFilter.PUBLIC_PROTECTED).toArray());
}

@Specialization
public RubyBasicObject methods(VirtualFrame frame, RubyBasicObject self, Object regular) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return methods(frame, self, booleanCastNode.executeBoolean(frame, regular));
@Specialization(guards = "!regular")
public RubyBasicObject methodsSingleton(VirtualFrame frame, Object self, boolean regular,
@Cached("createSingletonMethodsNode()") SingletonMethodsNode singletonMethodsNode) {
return singletonMethodsNode.executeSingletonMethods(frame, self, false);
}

protected MetaClassNode createMetaClassNode() {
return MetaClassNodeGen.create(getContext(), getSourceSection(), null);
}

protected SingletonMethodsNode createSingletonMethodsNode() {
return SingletonMethodsNodeFactory.create(getContext(), getSourceSection(), null, null);
}

}
@@ -1155,19 +1153,22 @@ public boolean isNil() {
}

@CoreMethod(names = "private_methods", optional = 1)
public abstract static class PrivateMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class PrivateMethodsNode extends CoreMethodNode {

@Child private MetaClassNode metaClassNode;
@Child private BooleanCastNode booleanCastNode;

public PrivateMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.metaClassNode = MetaClassNodeGen.create(context, sourceSection, null);
}

@Specialization
public RubyBasicObject privateMethods(VirtualFrame frame, Object self, NotProvided includeAncestors) {
return privateMethods(frame, self, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1179,15 +1180,6 @@ public RubyBasicObject privateMethods(VirtualFrame frame, Object self, boolean i
metaClass.filterMethodsOnObject(includeAncestors, MethodFilter.PRIVATE).toArray());
}

@Specialization
public RubyBasicObject privateMethods(VirtualFrame frame, RubyBasicObject self, Object includeAncestors) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return privateMethods(frame, self, booleanCastNode.executeBoolean(frame, includeAncestors));
}

}

@CoreMethod(names = "proc", isModuleFunction = true, needsBlock = true)
@@ -1209,19 +1201,22 @@ public RubyProc proc(RubyProc block) {
}

@CoreMethod(names = "protected_methods", optional = 1)
public abstract static class ProtectedMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class ProtectedMethodsNode extends CoreMethodNode {

@Child private MetaClassNode metaClassNode;
@Child private BooleanCastNode booleanCastNode;

public ProtectedMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.metaClassNode = MetaClassNodeGen.create(context, sourceSection, null);
}

@Specialization
public RubyBasicObject protectedMethods(VirtualFrame frame, Object self, NotProvided includeAncestors) {
return protectedMethods(frame, self, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1233,31 +1228,25 @@ public RubyBasicObject protectedMethods(VirtualFrame frame, Object self, boolean
metaClass.filterMethodsOnObject(includeAncestors, MethodFilter.PROTECTED).toArray());
}

@Specialization
public RubyBasicObject protectedMethods(VirtualFrame frame, RubyBasicObject self, Object includeAncestors) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return protectedMethods(frame, self, booleanCastNode.executeBoolean(frame, includeAncestors));
}

}

@CoreMethod(names = "public_methods", optional = 1)
public abstract static class PublicMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class PublicMethodsNode extends CoreMethodNode {

@Child private MetaClassNode metaClassNode;
@Child private BooleanCastNode booleanCastNode;

public PublicMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.metaClassNode = MetaClassNodeGen.create(context, sourceSection, null);
}

@Specialization
public RubyBasicObject publicMethods(VirtualFrame frame, Object self, NotProvided includeAncestors) {
return publicMethods(frame, self, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1269,15 +1258,6 @@ public RubyBasicObject publicMethods(VirtualFrame frame, Object self, boolean in
metaClass.filterMethodsOnObject(includeAncestors, MethodFilter.PUBLIC).toArray());
}

@Specialization
public RubyBasicObject publicMethods(VirtualFrame frame, RubyBasicObject self, Object includeAncestors) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return publicMethods(frame, self, booleanCastNode.executeBoolean(frame, includeAncestors));
}

}

@CoreMethod(names = "rand", isModuleFunction = true, optional = 1)
@@ -1413,7 +1393,12 @@ private String dirname(String path) {
}

@CoreMethod(names = "respond_to?", required = 1, optional = 1)
public abstract static class RespondToNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "name"),
@NodeChild(type = RubyNode.class, value = "includeProtectedAndPrivate")
})
public abstract static class RespondToNode extends CoreMethodNode {

@Child private DoesRespondDispatchHeadNode dispatch;
@Child private DoesRespondDispatchHeadNode dispatchIgnoreVisibility;
@@ -1430,40 +1415,25 @@ public RespondToNode(RubyContext context, SourceSection sourceSection) {
}
}

public abstract boolean executeDoesRespondTo(VirtualFrame frame, Object object, Object name, boolean includePrivate);
public abstract boolean executeDoesRespondTo(VirtualFrame frame, Object object, Object name, boolean includeProtectedAndPrivate);

@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, NotProvided checkVisibility) {
return doesRespondToString(frame, object, name, false);
@CreateCast("includeProtectedAndPrivate")
public RubyNode coerceToBoolean(RubyNode includeProtectedAndPrivate) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), false, includeProtectedAndPrivate);
}

@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, RubyBasicObject checkVisibility) {
return doesRespondToString(frame, object, name, false);
}

@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, boolean ignoreVisibility) {
if (ignoreVisibility) {
public boolean doesRespondToString(VirtualFrame frame, Object object, RubyBasicObject name, boolean includeProtectedAndPrivate) {
if (includeProtectedAndPrivate) {
return dispatchIgnoreVisibility.doesRespondTo(frame, name, object);
} else {
return dispatch.doesRespondTo(frame, name, object);
}
}

@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, NotProvided checkVisibility) {
return doesRespondToSymbol(frame, object, name, false);
}

@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, RubyBasicObject checkVisibility) {
return doesRespondToSymbol(frame, object, name, false);
}

@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, boolean ignoreVisibility) {
if (ignoreVisibility) {
public boolean doesRespondToSymbol(VirtualFrame frame, Object object, RubyBasicObject name, boolean includeProtectedAndPrivate) {
if (includeProtectedAndPrivate) {
return dispatchIgnoreVisibility.doesRespondTo(frame, name, object);
} else {
return dispatch.doesRespondTo(frame, name, object);
@@ -1480,22 +1450,12 @@ public RespondToMissingNode(RubyContext context, SourceSection sourceSection) {
}

@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToMissingString(Object object, RubyBasicObject name, NotProvided includeAll) {
return false;
}

@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToMissingSymbol(Object object, RubyBasicObject name, NotProvided includeAll) {
return false;
}

@Specialization(guards = "isRubyString(name)")
public boolean doesRespondToMissingString(Object object, RubyBasicObject name, boolean includeAll) {
public boolean doesRespondToMissingString(Object object, RubyBasicObject name, Object includeAll) {
return false;
}

@Specialization(guards = "isRubySymbol(name)")
public boolean doesRespondToMissingSymbol(Object object, RubyBasicObject name, boolean includeAll) {
public boolean doesRespondToMissingSymbol(Object object, RubyBasicObject name, Object includeAll) {
return false;
}

@@ -1543,10 +1503,13 @@ public RubyClass singletonClass(VirtualFrame frame, Object self) {
}

@CoreMethod(names = "singleton_methods", optional = 1)
public abstract static class SingletonMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "object"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class SingletonMethodsNode extends CoreMethodNode {

@Child private MetaClassNode metaClassNode;
@Child private BooleanCastNode booleanCastNode;

public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -1555,9 +1518,9 @@ public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) {

public abstract RubyBasicObject executeSingletonMethods(VirtualFrame frame, Object self, boolean includeAncestors);

@Specialization
public RubyBasicObject singletonMethods(VirtualFrame frame, Object self, NotProvided includeAncestors) {
return singletonMethods(frame, self, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1573,15 +1536,6 @@ public RubyBasicObject singletonMethods(VirtualFrame frame, Object self, boolean
metaClass.filterSingletonMethods(includeAncestors, MethodFilter.PUBLIC_PROTECTED).toArray());
}

@Specialization
public RubyBasicObject singletonMethods(VirtualFrame frame, Object self, Object includeAncestors) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return singletonMethods(frame, self, booleanCastNode.executeBoolean(frame, includeAncestors));
}

}

@CoreMethod(names = "String", isModuleFunction = true, required = 1)
108 changes: 51 additions & 57 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -34,6 +34,7 @@
import org.jruby.truffle.nodes.arguments.ReadPreArgumentNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeGen;
import org.jruby.truffle.nodes.cast.BooleanCastWithDefaultNodeGen;
import org.jruby.truffle.nodes.cast.TaintResultNode;
import org.jruby.truffle.nodes.coerce.*;
import org.jruby.truffle.nodes.constants.GetConstantNode;
@@ -763,25 +764,19 @@ public RubyBasicObject getClassVariables(RubyModule module) {
}

@CoreMethod(names = "constants", optional = 1)
public abstract static class ConstantsNode extends CoreMethodArrayArgumentsNode {

@Child BooleanCastNode booleanCastNode;
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "module"),
@NodeChild(type = RubyNode.class, value = "inherit")
})
public abstract static class ConstantsNode extends CoreMethodNode {

public ConstantsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

private boolean booleanCast(VirtualFrame frame, Object value) {
if (booleanCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
booleanCastNode = insert(BooleanCastNodeGen.create(getContext(), getSourceSection(), null));
}
return booleanCastNode.executeBoolean(frame, value);
}

@Specialization
public RubyBasicObject constants(RubyModule module, NotProvided inherit) {
return constants(module, true);
@CreateCast("inherit")
public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, inherit);
}

@Specialization
@@ -806,11 +801,6 @@ public RubyBasicObject constants(RubyModule module, boolean inherit) {
return ArrayNodes.fromObjects(getContext().getCoreLibrary().getArrayClass(), constantsArray.toArray(new Object[constantsArray.size()]));
}

@Specialization(guards = "wasProvided(inherit)")
public RubyBasicObject constants(VirtualFrame frame, RubyModule module, Object inherit) {
return constants(module, booleanCast(frame, inherit));
}

}

@CoreMethod(names = "const_defined?", required = 1, optional = 1)
@@ -830,9 +820,9 @@ public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(getContext(), getSourceSection(), name);
}

@Specialization
public boolean isConstDefined(RubyModule module, String name, NotProvided inherit) {
return isConstDefined(module, name, true);
@CreateCast("inherit")
public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, inherit);
}

@Specialization
@@ -864,12 +854,12 @@ public RubyNode coerceToString(RubyNode name) {
return NameToSymbolOrStringNodeGen.create(getContext(), getSourceSection(), name);
}

// Symbol
@Specialization(guards = "isRubySymbol(name)")
public Object getConstant(VirtualFrame frame, RubyModule module, RubyBasicObject name, NotProvided inherit) {
return getConstant(frame, module, name, true);
@CreateCast("inherit")
public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, inherit);
}

// Symbol
@Specialization(guards = {"inherit", "isRubySymbol(name)"})
public Object getConstant(VirtualFrame frame, RubyModule module, RubyBasicObject name, boolean inherit) {
return getConstantNode.executeGetConstant(frame, module, SymbolNodes.getString(name));
@@ -881,11 +871,6 @@ public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, RubyBa
}

// String
@Specialization(guards = "!isScoped(name)")
public Object getConstant(VirtualFrame frame, RubyModule module, RubyString name, NotProvided inherit) {
return getConstant(frame, module, name, true);
}

@Specialization(guards = { "inherit", "!isScoped(name)" })
public Object getConstant(VirtualFrame frame, RubyModule module, RubyString name, boolean inherit) {
return getConstantNode.executeGetConstant(frame, module, name.toString());
@@ -897,11 +882,6 @@ public Object getConstantNoInherit(VirtualFrame frame, RubyModule module, RubySt
}

// Scoped String
@Specialization(guards = "isScoped(fullName)")
public Object getConstantScoped(VirtualFrame frame, RubyModule module, RubyString fullName, NotProvided inherit) {
return getConstantScoped(frame, module, fullName, true);
}

@Specialization(guards = "isScoped(fullName)")
public Object getConstantScoped(VirtualFrame frame, RubyModule module, RubyString fullName, boolean inherit) {
return getConstantScoped(module, fullName.toString(), inherit);
@@ -1214,9 +1194,9 @@ public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(getContext(), getSourceSection(), name);
}

@Specialization
public boolean isMethodDefined(RubyModule module, String name, NotProvided inherit) {
return isMethodDefined(module, name, true);
@CreateCast("inherit")
public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, inherit);
}

@Specialization
@@ -1418,22 +1398,24 @@ public boolean isPrivateMethodDefined(RubyModule module, String name) {
}

@CoreMethod(names = "protected_instance_methods", optional = 1)
public abstract static class ProtectedInstanceMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "module"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class ProtectedInstanceMethodsNode extends CoreMethodNode {

public ProtectedInstanceMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject protectedInstanceMethods(RubyModule module, NotProvided includeAncestors) {
return protectedInstanceMethods(module, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
public RubyBasicObject protectedInstanceMethods(RubyModule module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();


return ArrayNodes.fromObjects(getContext().getCoreLibrary().getArrayClass(),
module.filterMethods(includeAncestors, MethodFilter.PROTECTED).toArray());
}
@@ -1466,15 +1448,19 @@ public boolean isProtectedMethodDefined(RubyModule module, String name) {
}

@CoreMethod(names = "private_instance_methods", optional = 1)
public abstract static class PrivateInstanceMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "module"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class PrivateInstanceMethodsNode extends CoreMethodNode {

public PrivateInstanceMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject privateInstanceMethods(RubyModule module, NotProvided includeAncestors) {
return privateInstanceMethods(module, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1523,15 +1509,19 @@ public RubyBasicObject publicInstanceMethod(RubyModule module, String name) {
}

@CoreMethod(names = "public_instance_methods", optional = 1)
public abstract static class PublicInstanceMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "module"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class PublicInstanceMethodsNode extends CoreMethodNode {

public PublicInstanceMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject publicInstanceMethods(RubyModule module, NotProvided includeAncestors) {
return publicInstanceMethods(module, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
@@ -1570,15 +1560,19 @@ public boolean isPublicMethodDefined(RubyModule module, String name) {
}

@CoreMethod(names = "instance_methods", optional = 1)
public abstract static class InstanceMethodsNode extends CoreMethodArrayArgumentsNode {
@NodeChildren({
@NodeChild(type = RubyNode.class, value = "module"),
@NodeChild(type = RubyNode.class, value = "includeAncestors")
})
public abstract static class InstanceMethodsNode extends CoreMethodNode {

public InstanceMethodsNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@Specialization
public RubyBasicObject instanceMethods(RubyModule module, NotProvided argument) {
return instanceMethods(module, true);
@CreateCast("includeAncestors")
public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(getContext(), getSourceSection(), true, includeAncestors);
}

@Specialization
Original file line number Diff line number Diff line change
@@ -371,7 +371,7 @@ public boolean equal(RubyString a, RubyString b) {
public boolean equal(VirtualFrame frame, RubyString a, Object b) {
if (respondToNode == null) {
CompilerDirectives.transferToInterpreter();
respondToNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null, null }));
respondToNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToNode.doesRespondToString(frame, b, (RubyString) StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "to_str"), false)) {
@@ -419,7 +419,7 @@ public Object compare(VirtualFrame frame, RubyString a, Object b) {

if (respondToToStrNode == null) {
CompilerDirectives.transferToInterpreter();
respondToToStrNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null, null }));
respondToToStrNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToToStrNode.doesRespondToString(frame, b, (RubyString) StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "to_str"), false)) {
@@ -443,7 +443,7 @@ public Object compare(VirtualFrame frame, RubyString a, Object b) {

if (respondToCmpNode == null) {
CompilerDirectives.transferToInterpreter();
respondToCmpNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[] { null, null, null }));
respondToCmpNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}

if (respondToCmpNode.doesRespondToString(frame, b, (RubyString) StringNodes.createString(getContext().getCoreLibrary().getStringClass(), "<=>"), false)) {
Original file line number Diff line number Diff line change
@@ -604,7 +604,7 @@ public Object mulObjectCount(VirtualFrame frame, RubyArray array, Object object)
CompilerDirectives.transferToInterpreter();
if (respondToToStrNode == null) {
CompilerDirectives.transferToInterpreter();
respondToToStrNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null, null}));
respondToToStrNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}
if (respondToToStrNode.doesRespondToString(frame, object, (RubyString) createString("to_str"), false)) {
return ruby(frame, "join(sep.to_str)", "sep", object);
@@ -1810,7 +1810,7 @@ public RubyBasicObject initialize(VirtualFrame frame, RubyArray array, Object ob
RubyArray copy = null;
if (respondToToAryNode == null) {
CompilerDirectives.transferToInterpreter();
respondToToAryNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{null, null, null}));
respondToToAryNode = insert(KernelNodesFactory.RespondToNodeFactory.create(getContext(), getSourceSection(), null, null, null));
}
if (respondToToAryNode.doesRespondToString(frame, object, (RubyString) createString("to_ary"), true)) {
if (toAryNode == null) {
Original file line number Diff line number Diff line change
@@ -250,7 +250,7 @@ public static abstract class VMObjectRespondToPrimitiveNode extends RubiniusPrim

public VMObjectRespondToPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
respondToNode = KernelNodesFactory.RespondToNodeFactory.create(context, sourceSection, new RubyNode[] { null, null, null });
respondToNode = KernelNodesFactory.RespondToNodeFactory.create(context, sourceSection, null, null, null);
}

@Specialization

1 comment on commit 1e55229

@eregon
Copy link
Member Author

@eregon eregon commented on 1e55229 Jun 17, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chrisseaton @nirvdrum @pitr-ch I added a special version of BooleanCastNode with a default value.
This was a fairly frequent case and removes the need for additional NotProvided and RubyBasicObject specializations.

Please sign in to comment.