Skip to content

Commit c3065ba

Browse files
committed
[Truffle] Reimplemented the :module_mirror primitive in Ruby to simplify corner cases.
1 parent c6b5cac commit c3065ba

File tree

4 files changed

+46
-27
lines changed

4 files changed

+46
-27
lines changed

truffle/src/main/java/org/jruby/truffle/nodes/rubinius/ModulePrimitiveNodes.java

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,33 @@
99
*/
1010
package org.jruby.truffle.nodes.rubinius;
1111

12-
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
13-
import com.oracle.truffle.api.dsl.Cached;
12+
import com.oracle.truffle.api.CompilerDirectives;
1413
import com.oracle.truffle.api.dsl.Specialization;
14+
import com.oracle.truffle.api.frame.VirtualFrame;
1515
import com.oracle.truffle.api.source.SourceSection;
16-
import org.jruby.truffle.runtime.RubyConstant;
16+
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
17+
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
1718
import org.jruby.truffle.runtime.RubyContext;
18-
import org.jruby.truffle.runtime.core.RubyBasicObject;
19-
import org.jruby.truffle.runtime.core.RubyClass;
20-
import org.jruby.truffle.runtime.core.RubyModule;
21-
2219

2320
public abstract class ModulePrimitiveNodes {
2421

2522
@RubiniusPrimitive(name = "module_mirror")
2623
public abstract static class ModuleMirrorPrimitiveNode extends RubiniusPrimitiveNode {
2724

25+
@Child private CallDispatchHeadNode moduleMirrorNode;
26+
2827
public ModuleMirrorPrimitiveNode(RubyContext context, SourceSection sourceSection) {
2928
super(context, sourceSection);
3029
}
3130

32-
@Specialization(guards = "logicalClass == object.getLogicalClass()")
33-
public Object moduleMirrorCached(RubyBasicObject object,
34-
@Cached("object.getLogicalClass()") RubyClass logicalClass,
35-
@Cached("lookupMirror(object)") Object mirror) {
36-
return mirror;
37-
}
38-
3931
@Specialization
40-
public Object moduleMirrorUncached(RubyBasicObject object) {
41-
return lookupMirror(object);
42-
}
43-
44-
@TruffleBoundary
45-
protected Object lookupMirror(RubyBasicObject object) {
46-
final RubyModule rubinius = (RubyModule) getContext().getCoreLibrary().getObjectClass().getConstants().get("Rubinius").getValue();
47-
final RubyModule mirror = (RubyModule) rubinius.getConstants().get("Mirror").getValue();
48-
final RubyConstant objectMirrorConstant = mirror.getConstants().get(object.getLogicalClass().getName());
49-
50-
if (objectMirrorConstant == null) {
51-
return nil();
32+
public Object moduleMirrorCached(VirtualFrame frame, Object reflectee) {
33+
if (moduleMirrorNode == null) {
34+
CompilerDirectives.transferToInterpreter();
35+
moduleMirrorNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), null));
5236
}
5337

54-
return objectMirrorConstant.getValue();
38+
return moduleMirrorNode.call(frame, getContext().getCoreLibrary().getRubiniusMirror(), "module_mirror", null, reflectee);
5539
}
5640

5741
}

truffle/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ public class CoreLibrary {
124124
private final RubyModule kernelModule;
125125
private final RubyModule rubiniusModule;
126126
private final RubyModule rubiniusFFIModule;
127+
private final RubyClass rubiniusMirrorModule;
127128
private final RubyModule signalModule;
128129
private final RubyModule truffleModule;
129130
private final RubyClass bigDecimalClass;
@@ -356,6 +357,8 @@ public CoreLibrary(RubyContext context) {
356357
rubiniusFFIModule = defineModule(rubiniusModule, "FFI");
357358
defineModule(defineModule(rubiniusFFIModule, "Platform"), "POSIX");
358359
defineClass(rubiniusFFIModule, objectClass, "Pointer", new PointerPrimitiveNodes.PointerAllocator());
360+
361+
rubiniusMirrorModule = defineClass(rubiniusModule, objectClass, "Mirror");
359362
defineModule(rubiniusModule, "Type");
360363

361364
byteArrayClass = defineClass(rubiniusModule, objectClass, "ByteArray");
@@ -1387,6 +1390,10 @@ public RubyClass getTupleClass() {
13871390
return tupleClass;
13881391
}
13891392

1393+
public RubyClass getRubiniusMirror() {
1394+
return rubiniusMirrorModule;
1395+
}
1396+
13901397
public RubyBasicObject getRubiniusUndefined() {
13911398
return rubiniusUndefined;
13921399
}

truffle/src/main/ruby/core.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
# Patch rubinius-core-api to make it work for us
1818

19+
require_relative 'core/rubinius/api/shims/mirror'
1920
require_relative 'core/rubinius/api/shims/lookuptable'
2021
require_relative 'core/rubinius/api/shims/array'
2122
require_relative 'core/rubinius/api/shims/rubinius'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
2+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
3+
# redistribute it and/or modify it under the terms of the:
4+
#
5+
# Eclipse Public License version 1.0
6+
# GNU General Public License version 2
7+
# GNU Lesser General Public License version 2.1
8+
9+
module Rubinius
10+
class Mirror
11+
12+
# Implementation of the :module_mirror Rubinius primitive.
13+
def self.module_mirror(obj)
14+
if obj.is_a?(::Numeric)
15+
Rubinius::Mirror::Numeric
16+
else
17+
begin
18+
Rubinius::Mirror.const_get(obj.class.name.to_sym, false)
19+
rescue NameError
20+
# TODO (nirvdrum 06-Jun-15) Rubinius defaults to Rubinius::Mirror::Object, but we don't have that yet. `nil` is safe based upon current usage.
21+
nil
22+
end
23+
end
24+
end
25+
26+
end
27+
end

0 commit comments

Comments
 (0)