Skip to content

Commit 6e0f8bd

Browse files
committed
Dispatch to Module#hash if not built-in
Fixes one failure in Zeitwerk that expected Module#hash to be called when a module was a key in a Hash.
1 parent ac4eade commit 6e0f8bd

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

core/src/main/java/org/jruby/RubyModule.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
import org.jruby.runtime.Constants;
108108
import org.jruby.runtime.Helpers;
109109
import org.jruby.runtime.IRBlockBody;
110+
import org.jruby.runtime.JavaSites;
110111
import org.jruby.runtime.MethodFactory;
111112
import org.jruby.runtime.MethodIndex;
112113
import org.jruby.runtime.ObjectAllocator;
@@ -118,6 +119,7 @@
118119
import org.jruby.runtime.builtin.IRubyObject;
119120
import org.jruby.runtime.builtin.Variable;
120121
import org.jruby.runtime.callsite.CacheEntry;
122+
import org.jruby.runtime.callsite.CachingCallSite;
121123
import org.jruby.runtime.load.LoadService;
122124
import org.jruby.runtime.marshal.MarshalDumper;
123125
import org.jruby.runtime.marshal.MarshalLoader;
@@ -3199,7 +3201,22 @@ public boolean hasModuleInHierarchy(RubyModule type) {
31993201

32003202
@Override
32013203
public int hashCode() {
3202-
return id;
3204+
RubyClass metaClass = this.metaClass;
3205+
3206+
// may be null during boot
3207+
if (metaClass == null) return id;
3208+
3209+
Ruby runtime = metaClass.getClassRuntime();
3210+
3211+
if (runtime.isBooting()) return id;
3212+
3213+
ThreadContext context = runtime.getCurrentContext();
3214+
CachingCallSite hash = sites(context).hash;
3215+
3216+
if (hash.isBuiltin(this)) return id;
3217+
3218+
// we truncate for Java hashcode
3219+
return (int) hash.call(context, this, this).convertToInteger().getLongValue();
32033220
}
32043221

32053222
@JRubyMethod(name = "hash")
@@ -6985,6 +7002,10 @@ private class RefinementStore {
69857002
.from(boolean.class, ThreadContext.class, IRubyObject.class, int.class)
69867003
.invokeStaticQuiet(LOOKUP, RubyModule.class, "testModuleMatch");
69877004

7005+
public static JavaSites.ModuleSites sites(ThreadContext context) {
7006+
return context.sites.Module;
7007+
}
7008+
69887009
@Deprecated
69897010
public IRubyObject const_get(IRubyObject symbol) {
69907011
return const_get(getCurrentContext(), symbol);

core/src/main/java/org/jruby/runtime/JavaSites.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public class JavaSites {
5757
public final MethodSites Method = new MethodSites();
5858
public final SymbolSites Symbol = new SymbolSites();
5959
public final ProcSites Proc = new ProcSites();
60+
public final ModuleSites Module = new ModuleSites();
6061

6162
public static class BasicObjectSites {
6263
public final CallSite respond_to = new FunctionalCachingCallSite("respond_to?");
@@ -566,6 +567,10 @@ public static class ProcSites {
566567
public final CallSite initialize_dup = new FunctionalCachingCallSite("initialize_dup");
567568
}
568569

570+
public static class ModuleSites {
571+
public final CachingCallSite hash = new FunctionalCachingCallSite("hash");
572+
}
573+
569574
public static class CheckedSites {
570575
public final RespondToCallSite respond_to_X;
571576
public final CachingCallSite respond_to_missing = new FunctionalCachingCallSite("respond_to_missing?");

0 commit comments

Comments
 (0)