Skip to content

Commit 5d1e74f

Browse files
committed
Fix Kernel#{method,public_method} to always pass a Symbol to #respond_to_missing? and #method_missing
1 parent d0f5ad9 commit 5d1e74f

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/main/java/org/truffleruby/language/methods/GetMethodObjectNode.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
import org.truffleruby.core.array.ArrayUtils;
2828
import org.truffleruby.core.cast.BooleanCastNode;
2929
import org.truffleruby.core.cast.NameToJavaStringNode;
30+
import org.truffleruby.core.cast.ToSymbolNode;
3031
import org.truffleruby.core.klass.RubyClass;
3132
import org.truffleruby.core.method.RubyMethod;
33+
import org.truffleruby.core.symbol.RubySymbol;
3234
import org.truffleruby.language.RubyBaseNode;
3335
import org.truffleruby.language.RubyContextSourceNode;
3436
import org.truffleruby.language.RubyNode;
@@ -62,6 +64,7 @@ protected RubyMethod getMethodObject(
6264
@CachedContext(RubyLanguage.class) RubyContext context,
6365
@Cached NameToJavaStringNode nameToJavaStringNode,
6466
@Cached LookupMethodOnSelfNode lookupMethodNode,
67+
@Cached ToSymbolNode toSymbolNode,
6568
@Cached DispatchNode respondToMissingNode,
6669
@Cached BooleanCastNode booleanCastNode,
6770
@Cached ConditionProfile notFoundProfile,
@@ -80,18 +83,20 @@ protected RubyMethod getMethodObject(
8083
}
8184

8285
final String normalizedName = nameToJavaStringNode.execute(name);
83-
InternalMethod method = lookupMethodNode
84-
.execute(frame, self, normalizedName, dispatchConfig);
86+
InternalMethod method = lookupMethodNode.execute(frame, self, normalizedName, dispatchConfig);
8587

8688
if (notFoundProfile.profile(method == null)) {
89+
final RubySymbol symbolName = toSymbolNode.execute(name);
8790
final Object respondToMissing = respondToMissingNode
88-
.call(self, "respond_to_missing?", name, dispatchConfig.ignoreVisibility);
91+
.call(self, "respond_to_missing?", symbolName, dispatchConfig.ignoreVisibility);
8992
if (respondToMissingProfile.profile(booleanCastNode.executeToBoolean(respondToMissing))) {
90-
/** refinements should not affect BasicObject#method_missing */
91-
RubyArguments.setDeclarationContext(frame, originalDeclarationContext);
93+
if (frame != null) {
94+
// refinements should not affect BasicObject#method_missing
95+
RubyArguments.setDeclarationContext(frame, originalDeclarationContext);
96+
}
9297
final InternalMethod methodMissing = lookupMethodNode
9398
.execute(frame, self, "method_missing", dispatchConfig);
94-
method = createMissingMethod(self, name, normalizedName, methodMissing, language, context);
99+
method = createMissingMethod(self, symbolName, normalizedName, methodMissing, language, context);
95100
} else {
96101
throw new RaiseException(
97102
context,
@@ -111,7 +116,7 @@ protected RubyMethod getMethodObject(
111116
}
112117

113118
@TruffleBoundary
114-
private InternalMethod createMissingMethod(Object self, Object name, String normalizedName,
119+
private InternalMethod createMissingMethod(Object self, RubySymbol name, String normalizedName,
115120
InternalMethod methodMissing, RubyLanguage language, RubyContext context) {
116121
final SharedMethodInfo info = methodMissing
117122
.getSharedMethodInfo()
@@ -140,10 +145,11 @@ private InternalMethod createMissingMethod(Object self, Object name, String norm
140145
}
141146

142147
private static class CallMethodMissingWithStaticName extends RubyContextSourceNode {
143-
private final Object methodName;
148+
149+
private final RubySymbol methodName;
144150
@Child private DispatchNode methodMissing = DispatchNode.create();
145151

146-
public CallMethodMissingWithStaticName(Object methodName) {
152+
public CallMethodMissingWithStaticName(RubySymbol methodName) {
147153
this.methodName = methodName;
148154
}
149155

0 commit comments

Comments
 (0)