Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9ed322498be6
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 76d90de18c92
Choose a head ref
  • 2 commits
  • 5 files changed
  • 1 contributor

Commits on May 6, 2016

  1. Copy the full SHA
    2738304 View commit details
  2. Copy the full SHA
    76d90de View commit details
Original file line number Diff line number Diff line change
@@ -753,7 +753,7 @@ public void addCoreMethods() {

coreMethodNodeManager.allMethodInstalled();

basicObjectSendMethod = Layouts.MODULE.getFields(basicObjectClass).getMethods().get("__send__");
basicObjectSendMethod = Layouts.MODULE.getFields(basicObjectClass).getMethod("__send__");
assert basicObjectSendMethod != null;
}

Original file line number Diff line number Diff line change
@@ -503,8 +503,13 @@ public RubyConstant getConstant(String name) {
return constants.get(name);
}

public Map<String, InternalMethod> getMethods() {
return methods;
public Iterable<InternalMethod> getMethods() {
return methods.values();
}

@TruffleBoundary
public InternalMethod getMethod(String name) {
return methods.get(name);
}

public ConcurrentMap<String, Object> getClassVariables() {
@@ -562,7 +567,7 @@ public Collection<DynamicObject> filterMethods(RubyContext context, boolean incl
if (includeAncestors) {
allMethods = ModuleOperations.getAllMethods(rubyModuleObject);
} else {
allMethods = getMethods();
allMethods = methods;
}
return filterMethods(context, allMethods, filter);
}
@@ -582,7 +587,7 @@ public Collection<DynamicObject> filterSingletonMethods(RubyContext context, boo
if (includeAncestors) {
allMethods = ModuleOperations.getMethodsBeforeLogicalClass(rubyModuleObject);
} else {
allMethods = getMethods();
allMethods = methods;
}
return filterMethods(context, allMethods, filter);
}
142 changes: 52 additions & 90 deletions truffle/src/main/java/org/jruby/truffle/core/module/ModuleNodes.java
Original file line number Diff line number Diff line change
@@ -86,6 +86,8 @@
import org.jruby.truffle.language.methods.SharedMethodInfo;
import org.jruby.truffle.language.objects.IsANode;
import org.jruby.truffle.language.objects.IsANodeGen;
import org.jruby.truffle.language.objects.IsFrozenNode;
import org.jruby.truffle.language.objects.IsFrozenNodeGen;
import org.jruby.truffle.language.objects.ReadInstanceVariableNode;
import org.jruby.truffle.language.objects.SelfNode;
import org.jruby.truffle.language.objects.SingletonClassNode;
@@ -96,7 +98,6 @@
import org.jruby.truffle.language.yield.YieldNode;
import org.jruby.truffle.platform.UnsafeGroup;
import org.jruby.util.IdUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -142,10 +143,9 @@ public abstract static class IsSubclassOfNode extends CoreMethodArrayArgumentsNo

public abstract Object executeIsSubclassOf(VirtualFrame frame, DynamicObject self, DynamicObject other);

@TruffleBoundary
@Specialization(guards = "isRubyModule(other)")
public Object isSubclassOf(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();

public Object isSubclassOf(DynamicObject self, DynamicObject other) {
if (self == other) {
return false;
}
@@ -162,8 +162,7 @@ public Object isSubclassOf(VirtualFrame frame, DynamicObject self, DynamicObject
}

@Specialization(guards = "!isRubyModule(other)")
public Object isSubclassOfOther(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();
public Object isSubclassOfOther(DynamicObject self, DynamicObject other) {
throw new RaiseException(coreExceptions().typeError("compared with non class/module", this));
}

@@ -172,12 +171,11 @@ public Object isSubclassOfOther(VirtualFrame frame, DynamicObject self, DynamicO
@CoreMethod(names = "<=", required = 1)
public abstract static class IsSubclassOfOrEqualToNode extends CoreMethodArrayArgumentsNode {

public abstract Object executeIsSubclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, DynamicObject other);
public abstract Object executeIsSubclassOfOrEqualTo(DynamicObject self, DynamicObject other);

@TruffleBoundary
@Specialization(guards = "isRubyModule(other)")
public Object isSubclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();

public Object isSubclassOfOrEqualTo(DynamicObject self, DynamicObject other) {
if (self == other || ModuleOperations.includesModule(self, other)) {
return true;
}
@@ -190,8 +188,7 @@ public Object isSubclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, Dyna
}

@Specialization(guards = "!isRubyModule(other)")
public Object isSubclassOfOrEqualToOther(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();
public Object isSubclassOfOrEqualToOther(DynamicObject self, DynamicObject other) {
throw new RaiseException(coreExceptions().typeError("compared with non class/module", this));
}

@@ -202,10 +199,9 @@ public abstract static class IsSuperclassOfNode extends CoreMethodArrayArguments

public abstract Object executeIsSuperclassOf(VirtualFrame frame, DynamicObject self, DynamicObject other);

@TruffleBoundary
@Specialization(guards = "isRubyModule(other)")
public Object isSuperclassOf(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();

public Object isSuperclassOf(DynamicObject self, DynamicObject other) {
if (self == other) {
return false;
}
@@ -222,8 +218,7 @@ public Object isSuperclassOf(VirtualFrame frame, DynamicObject self, DynamicObje
}

@Specialization(guards = "!isRubyModule(other)")
public Object isSuperclassOfOther(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();
public Object isSuperclassOfOther(DynamicObject self, DynamicObject other) {
throw new RaiseException(coreExceptions().typeError("compared with non class/module", this));
}

@@ -234,10 +229,9 @@ public abstract static class IsSuperclassOfOrEqualToNode extends CoreMethodArray

public abstract Object executeIsSuperclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, DynamicObject other);

@TruffleBoundary
@Specialization(guards = "isRubyModule(other)")
public Object isSuperclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();

public Object isSuperclassOfOrEqualTo(DynamicObject self, DynamicObject other) {
if (self == other || ModuleOperations.includesModule(other, self)) {
return true;
}
@@ -250,8 +244,7 @@ public Object isSuperclassOfOrEqualTo(VirtualFrame frame, DynamicObject self, Dy
}

@Specialization(guards = "!isRubyModule(other)")
public Object isSuperclassOfOrEqualToOther(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();
public Object isSuperclassOfOrEqualToOther(DynamicObject self, DynamicObject other) {
throw new RaiseException(coreExceptions().typeError("compared with non class/module", this));
}

@@ -261,44 +254,32 @@ public Object isSuperclassOfOrEqualToOther(VirtualFrame frame, DynamicObject sel
public abstract static class CompareNode extends CoreMethodArrayArgumentsNode {

@Child private IsSubclassOfOrEqualToNode subclassNode;
@Child private BooleanCastNode booleanCastNode;

private Object isSubclass(VirtualFrame frame, DynamicObject self, DynamicObject other) {
private Object isSubclass(DynamicObject self, DynamicObject other) {
if (subclassNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
subclassNode = insert(ModuleNodesFactory.IsSubclassOfOrEqualToNodeFactory.create(new RubyNode[]{null, null}));
}
return subclassNode.executeIsSubclassOfOrEqualTo(frame, self, other);
}

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

@Specialization(guards = "isRubyModule(other)")
public Object compare(VirtualFrame frame, DynamicObject self, DynamicObject other) {
CompilerDirectives.transferToInterpreter();

public Object compare(DynamicObject self, DynamicObject other) {
if (self == other) {
return 0;
}

final Object isSubclass = isSubclass(frame, self, other);
final Object isSubclass = isSubclass(self, other);

if (isSubclass == nil()) {
return nil();
} else if (booleanCast(frame, isSubclass)) {
return -1;
} else {
return (boolean) isSubclass ? -1 : 1;
}
return 1;
}

@Specialization(guards = "!isRubyModule(other)")
public Object compareOther(VirtualFrame frame, DynamicObject self, DynamicObject other) {
public Object compareOther(DynamicObject self, DynamicObject other) {
return nil();
}

@@ -333,10 +314,9 @@ public DynamicObject aliasMethod(DynamicObject module, String newName, String ol
@CoreMethod(names = "ancestors")
public abstract static class AncestorsNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject ancestors(DynamicObject self) {
CompilerDirectives.transferToInterpreter();

final List<DynamicObject> ancestors = new ArrayList<>();
for (DynamicObject module : Layouts.MODULE.getFields(self).ancestors()) {
ancestors.add(module);
@@ -386,8 +366,12 @@ public GenerateAccessorNode(RubyContext context, SourceSection sourceSection, bo
@Specialization
public DynamicObject generateAccessor(VirtualFrame frame, DynamicObject module, Object nameObject) {
final String name = nameToJavaStringNode.executeToJavaString(frame, nameObject);
createAccesor(module, name);
return nil();
}

CompilerDirectives.transferToInterpreter();
@TruffleBoundary
private void createAccesor(DynamicObject module, String name) {
final FrameInstance callerFrame = getContext().getCallStack().getCallerFrameIgnoringSend();
final SourceSection sourceSection = callerFrame.getCallNode().getEncapsulatingSourceSection();
final Visibility visibility = DeclarationContext.findVisibility(callerFrame.getFrame(FrameAccess.READ_ONLY, true));
@@ -413,7 +397,6 @@ public DynamicObject generateAccessor(VirtualFrame frame, DynamicObject module,
final InternalMethod method = new InternalMethod(sharedMethodInfo, accessorName, module, visibility, callTarget);

Layouts.MODULE.getFields(module).addMethod(getContext(), this, method);
return nil();
}
}

@@ -521,14 +504,11 @@ public DynamicObject attrWriter(VirtualFrame frame, DynamicObject module, Object
})
public abstract static class AutoloadNode extends CoreMethodNode {

@Child private StringNodes.EmptyNode emptyNode;
private final ConditionProfile invalidConstantName = ConditionProfile.createBinaryProfile();
private final ConditionProfile emptyFilename = ConditionProfile.createBinaryProfile();
private final ConditionProfile alreadyLoaded = ConditionProfile.createBinaryProfile();
@Child private StringNodes.IsEmptyNode isEmptyNode;

public AutoloadNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
emptyNode = StringNodesFactory.EmptyNodeFactory.create(new RubyNode[]{});
isEmptyNode = StringNodesFactory.IsEmptyNodeFactory.create(new RubyNode[] {});
}

@CreateCast("name") public RubyNode coerceNameToString(RubyNode name) {
@@ -539,19 +519,18 @@ public AutoloadNode(RubyContext context, SourceSection sourceSection) {
return ToPathNodeGen.create(null, null, filename);
}

@TruffleBoundary
@Specialization(guards = "isRubyString(filename)")
public DynamicObject autoload(DynamicObject module, String name, DynamicObject filename) {
if (invalidConstantName.profile(!IdUtil.isValidConstantName19(name))) {
CompilerDirectives.transferToInterpreter();
if (IdUtil.isValidConstantName19(name)) {
throw new RaiseException(coreExceptions().nameError(String.format("autoload must be constant name: %s", name), name, this));
}

if (emptyFilename.profile(emptyNode.empty(filename))) {
CompilerDirectives.transferToInterpreter();
if (isEmptyNode.executeIsEmpty(filename)) {
throw new RaiseException(coreExceptions().argumentError("empty file name", this));
}

if (alreadyLoaded.profile(Layouts.MODULE.getFields(module).getConstant(name) != null)) {
if (Layouts.MODULE.getFields(module).getConstant(name) != null) {
return nil();
}

@@ -659,13 +638,11 @@ public Object classEval(VirtualFrame frame, DynamicObject self, NotProvided code

@Specialization
public Object classEval(DynamicObject self, NotProvided code, NotProvided file, NotProvided line, NotProvided block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().argumentError(0, 1, 2, this));
}

@Specialization(guards = "wasProvided(code)")
public Object classEval(DynamicObject self, Object code, NotProvided file, NotProvided line, DynamicObject block) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().argumentError(1, 0, this));
}

@@ -689,8 +666,7 @@ public Object classExec(VirtualFrame frame, DynamicObject self, Object[] args, D
}

@Specialization
public Object classExec(VirtualFrame frame, DynamicObject self, Object[] args, NotProvided block) {
CompilerDirectives.transferToInterpreter();
public Object classExec(DynamicObject self, Object[] args, NotProvided block) {
throw new RaiseException(coreExceptions().noBlockGiven(this));
}

@@ -740,7 +716,6 @@ public Object getClassVariable(DynamicObject module, String name) {
final Object value = ModuleOperations.lookupClassVariable(module, name);

if (value == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().nameErrorUninitializedClassVariable(module, name, this));
} else {
return value;
@@ -804,10 +779,9 @@ public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(null, null, true, inherit);
}

@TruffleBoundary
@Specialization
public DynamicObject constants(DynamicObject module, boolean inherit) {
CompilerDirectives.transferToInterpreter();

final List<DynamicObject> constantsArray = new ArrayList<>();

final Iterable<Entry<String, RubyConstant>> constants;
@@ -847,9 +821,9 @@ public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(null, null, true, inherit);
}

@TruffleBoundary
@Specialization
public boolean isConstDefined(DynamicObject module, String fullName, boolean inherit) {
CompilerDirectives.transferToInterpreter();
return ModuleOperations.lookupScopedConstant(getContext(), module, fullName, inherit, this) != null;
}

@@ -911,10 +885,10 @@ public Object getConstantScoped(DynamicObject module, DynamicObject fullName, bo
}

private Object getConstantNoInherit(VirtualFrame frame, DynamicObject module, String name, Node currentNode) {
RubyConstant constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);
CompilerDirectives.transferToInterpreter();

RubyConstant constant = ModuleOperations.lookupConstantWithInherit(getContext(), module, name, false, currentNode);
if (constant == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().nameErrorUninitializedConstant(module, name, this));
} else {
if (constant.isAutoload()) {
@@ -930,7 +904,6 @@ private Object getConstantNoInherit(VirtualFrame frame, DynamicObject module, St
private Object getConstantScoped(DynamicObject module, String fullName, boolean inherit) {
RubyConstant constant = ModuleOperations.lookupScopedConstant(getContext(), module, fullName, inherit, this);
if (constant == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().nameErrorUninitializedConstant(module, fullName, this));
} else {
return constant.getValue();
@@ -993,10 +966,9 @@ public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(null, null, name);
}

@TruffleBoundary
@Specialization
public Object setConstant(DynamicObject module, String name, Object value) {
CompilerDirectives.transferToInterpreter();

if (!IdUtil.isValidConstantName19(name)) {
throw new RaiseException(coreExceptions().nameError(String.format("wrong constant name %s", name), name, this));
}
@@ -1053,7 +1025,6 @@ public DynamicObject defineMethodMethod(DynamicObject module, String name, Dynam
final InternalMethod method = Layouts.METHOD.getMethod(methodObject);

if (!canBindMethodToModuleNode.executeCanBindMethodToModule(method, module)) {
CompilerDirectives.transferToInterpreter();
final DynamicObject declaringModule = method.getDeclaringModule();
if (RubyGuards.isRubyClass(declaringModule) && Layouts.CLASS.getIsSingleton(declaringModule)) {
throw new RaiseException(coreExceptions().typeError(
@@ -1068,13 +1039,11 @@ public DynamicObject defineMethodMethod(DynamicObject module, String name, Dynam
return getSymbol(name);
}

@TruffleBoundary
@Specialization(guards = "isRubyUnboundMethod(method)")
public DynamicObject defineMethod(VirtualFrame frame, DynamicObject module, String name, DynamicObject method, NotProvided block) {
CompilerDirectives.transferToInterpreter();

public DynamicObject defineMethod(DynamicObject module, String name, DynamicObject method, NotProvided block) {
final DynamicObject origin = Layouts.UNBOUND_METHOD.getOrigin(method);
if (!ModuleOperations.canBindMethodTo(origin, module)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().typeError("bind argument must be a subclass of " + Layouts.MODULE.getFields(origin).getName(), this));
}

@@ -1221,10 +1190,9 @@ public DynamicObject included(Object subclass) {
@CoreMethod(names = "included_modules")
public abstract static class IncludedModulesNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject includedModules(DynamicObject module) {
CompilerDirectives.transferToInterpreter();

final List<DynamicObject> modules = new ArrayList<>();

for (DynamicObject included : Layouts.MODULE.getFields(module).ancestors()) {
@@ -1255,15 +1223,14 @@ public RubyNode coerceToBoolean(RubyNode inherit) {
return BooleanCastWithDefaultNodeGen.create(null, null, true, inherit);
}

@TruffleBoundary
@Specialization
public boolean isMethodDefined(DynamicObject module, String name, boolean inherit) {
CompilerDirectives.transferToInterpreter();

final InternalMethod method;
if (inherit) {
method = ModuleOperations.lookupMethod(module, name);
} else {
method = Layouts.MODULE.getFields(module).getMethods().get(name);
method = Layouts.MODULE.getFields(module).getMethod(name);
}

return method != null && !method.getVisibility().isPrivate();
@@ -1312,10 +1279,9 @@ public Object name(DynamicObject module,
@CoreMethod(names = "nesting", onSingleton = true)
public abstract static class NestingNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
public DynamicObject nesting() {
CompilerDirectives.transferToInterpreter();

final List<DynamicObject> modules = new ArrayList<>();

InternalMethod method = getContext().getCallStack().getCallingMethodIgnoringSend();
@@ -1494,8 +1460,6 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
@Specialization
@TruffleBoundary
public DynamicObject getInstanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

Object[] objects = Layouts.MODULE.getFields(module).filterMethods(getContext(), includeAncestors, MethodFilter.by(visibility)).toArray();
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length);
}
@@ -1594,10 +1558,9 @@ public RubyNode coerceToBoolean(RubyNode includeAncestors) {
return BooleanCastWithDefaultNodeGen.create(null, null, true, includeAncestors);
}

@TruffleBoundary
@Specialization
public DynamicObject instanceMethods(DynamicObject module, boolean includeAncestors) {
CompilerDirectives.transferToInterpreter();

Object[] objects = Layouts.MODULE.getFields(module).filterMethods(getContext(), includeAncestors, MethodFilter.PUBLIC_PROTECTED).toArray();
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), objects, objects.length);
}
@@ -1720,11 +1683,11 @@ public RubyNode coerceToString(RubyNode name) {
return NameToJavaStringNodeGen.create(null, null, name);
}

@TruffleBoundary
@Specialization
Object removeConstant(DynamicObject module, String name) {
RubyConstant oldConstant = Layouts.MODULE.getFields(module).removeConstant(getContext(), this, name);
if (oldConstant == null) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreExceptions().nameErrorConstantNotDefined(module, name, this));
} else {
if (oldConstant.isAutoload()) {
@@ -1741,13 +1704,13 @@ Object removeConstant(DynamicObject module, String name) {
public abstract static class RemoveMethodNode extends CoreMethodArrayArgumentsNode {

@Child NameToJavaStringNode nameToJavaStringNode;
@Child RaiseIfFrozenNode raiseIfFrozenNode;
@Child IsFrozenNode isFrozenNode;
@Child CallDispatchHeadNode methodRemovedNode;

public RemoveMethodNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.nameToJavaStringNode = NameToJavaStringNodeGen.create(context, sourceSection, null);
this.raiseIfFrozenNode = new RaiseIfFrozenNode(new SelfNode(context, sourceSection));
this.isFrozenNode = IsFrozenNodeGen.create(context, sourceSection, null);
this.methodRemovedNode = DispatchHeadNodeFactory.createMethodCallOnSelf(context);
}

@@ -1760,10 +1723,9 @@ public DynamicObject removeMethods(VirtualFrame frame, DynamicObject module, Obj
}

private void removeMethod(VirtualFrame frame, DynamicObject module, String name) {
raiseIfFrozenNode.execute(frame);
isFrozenNode.raiseIfFrozen(module);

CompilerDirectives.transferToInterpreter();
if (Layouts.MODULE.getFields(module).getMethods().containsKey(name)) {
if (Layouts.MODULE.getFields(module).getMethod(name) != null) {
Layouts.MODULE.getFields(module).removeMethod(name);
methodRemovedNode.call(frame, module, "method_removed", null, getSymbol(name));
} else {
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@
public abstract class ModuleOperations {

public static boolean includesModule(DynamicObject module, DynamicObject other) {
CompilerAsserts.neverPartOfCompilation();
assert RubyGuards.isRubyModule(module);
//assert RubyGuards.isRubyModule(other);

@@ -212,7 +213,7 @@ public static Map<String, InternalMethod> getAllMethods(DynamicObject module) {
final Map<String, InternalMethod> methods = new HashMap<>();

for (DynamicObject ancestor : Layouts.MODULE.getFields(module).ancestors()) {
for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods().values()) {
for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods()) {
if (!methods.containsKey(method.getName())) {
methods.put(method.getName(), method);
}
@@ -234,7 +235,7 @@ public static Map<String, InternalMethod> getMethodsBeforeLogicalClass(DynamicOb
break;
}

for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods().values()) {
for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods()) {
if (!methods.containsKey(method.getName())) {
methods.put(method.getName(), method);
}
@@ -251,7 +252,7 @@ public static Map<String, InternalMethod> getMethodsUntilLogicalClass(DynamicObj
final Map<String, InternalMethod> methods = new HashMap<>();

for (DynamicObject ancestor : Layouts.MODULE.getFields(module).ancestors()) {
for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods().values()) {
for (InternalMethod method : Layouts.MODULE.getFields(ancestor).getMethods()) {
if (!methods.containsKey(method.getName())) {
methods.put(method.getName(), method);
}
@@ -285,7 +286,7 @@ public static InternalMethod lookupMethod(DynamicObject module, String name) {

// Look in ancestors
for (DynamicObject ancestor : Layouts.MODULE.getFields(module).ancestors()) {
InternalMethod method = Layouts.MODULE.getFields(ancestor).getMethods().get(name);
InternalMethod method = Layouts.MODULE.getFields(ancestor).getMethod(name);

if (method != null) {
return method;
@@ -317,7 +318,7 @@ public static InternalMethod lookupSuperMethod(DynamicObject declaringModule, St
if (module == declaringModule) {
foundDeclaringModule = true;
} else if (foundDeclaringModule) {
InternalMethod method = Layouts.MODULE.getFields(module).getMethods().get(name);
InternalMethod method = Layouts.MODULE.getFields(module).getMethod(name);

if (method != null) {
return method;
Original file line number Diff line number Diff line change
@@ -1124,7 +1124,9 @@ private Object substr(Rope rope, DynamicObject string, int beg, int len) {
}

@CoreMethod(names = "empty?")
public abstract static class EmptyNode extends CoreMethodArrayArgumentsNode {
public abstract static class IsEmptyNode extends CoreMethodArrayArgumentsNode {

public abstract boolean executeIsEmpty(DynamicObject string);

@Specialization
public boolean empty(DynamicObject string) {