Skip to content

Commit 3e4f49c

Browse files
committed
[Truffle] Store the visibility in the frame and walk the frames to find it.
1 parent fda9948 commit 3e4f49c

File tree

5 files changed

+54
-19
lines changed

5 files changed

+54
-19
lines changed

core/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ public ClassExecNode(ClassExecNode prev) {
459459
public abstract Object executeClassEval(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block);
460460

461461
@Specialization
462-
public Object classEval(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block) {
462+
public Object classExec(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block) {
463463
notDesignedForCompilation();
464464

465465
// TODO: deal with args

core/src/main/java/org/jruby/truffle/nodes/methods/MethodDefinitionNode.java

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@
1111

1212
import com.oracle.truffle.api.CallTarget;
1313
import com.oracle.truffle.api.Truffle;
14+
import com.oracle.truffle.api.frame.Frame;
15+
import com.oracle.truffle.api.frame.FrameInstance;
16+
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
17+
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
1418
import com.oracle.truffle.api.frame.FrameSlot;
1519
import com.oracle.truffle.api.frame.FrameSlotTypeException;
1620
import com.oracle.truffle.api.frame.MaterializedFrame;
1721
import com.oracle.truffle.api.frame.VirtualFrame;
1822
import com.oracle.truffle.api.nodes.NodeUtil;
1923
import com.oracle.truffle.api.source.SourceSection;
24+
2025
import org.jruby.runtime.Visibility;
2126
import org.jruby.truffle.nodes.RubyNode;
2227
import org.jruby.truffle.nodes.RubyRootNode;
28+
import org.jruby.truffle.runtime.RubyArguments;
2329
import org.jruby.truffle.runtime.RubyContext;
2430
import org.jruby.truffle.runtime.core.RubyModule;
2531
import org.jruby.truffle.runtime.methods.RubyMethod;
@@ -71,29 +77,39 @@ public RubyMethod executeMethod(VirtualFrame frame, MaterializedFrame declaratio
7177
}
7278

7379
private Visibility getVisibility(VirtualFrame frame) {
80+
notDesignedForCompilation();
81+
7482
if (ignoreLocalVisibility) {
7583
return Visibility.PUBLIC;
7684
} else if (name.equals("initialize") || name.equals("initialize_copy") || name.equals("initialize_clone") || name.equals("initialize_dup") || name.equals("respond_to_missing?")) {
7785
return Visibility.PRIVATE;
7886
} else {
79-
final FrameSlot visibilitySlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
80-
81-
if (visibilitySlot == null) {
82-
return Visibility.PUBLIC;
83-
} else {
84-
Object visibilityObject;
87+
// Ignore scopes who do not have a visibility slot.
88+
Visibility currentFrameVisibility = findVisibility(frame);
89+
if (currentFrameVisibility != null) {
90+
return currentFrameVisibility;
91+
}
8592

86-
try {
87-
visibilityObject = frame.getObject(visibilitySlot);
88-
} catch (FrameSlotTypeException e) {
89-
throw new RuntimeException(e);
93+
return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Visibility>() {
94+
@Override
95+
public Visibility visitFrame(FrameInstance frameInstance) {
96+
Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY, true);
97+
return findVisibility(frame);
9098
}
99+
});
100+
}
101+
}
91102

92-
if (visibilityObject instanceof Visibility) {
93-
return (Visibility) visibilityObject;
94-
} else {
95-
return Visibility.PUBLIC;
96-
}
103+
private static Visibility findVisibility(Frame frame) {
104+
FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
105+
if (slot == null) {
106+
return null;
107+
} else {
108+
Object visibilityObject = frame.getValue(slot);
109+
if (visibilityObject instanceof Visibility) {
110+
return (Visibility) visibilityObject;
111+
} else {
112+
return Visibility.PUBLIC;
97113
}
98114
}
99115
}

core/src/main/java/org/jruby/truffle/nodes/yield/YieldDispatchHeadNode.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@
99
*/
1010
package org.jruby.truffle.nodes.yield;
1111

12+
import com.oracle.truffle.api.Truffle;
13+
import com.oracle.truffle.api.frame.Frame;
14+
import com.oracle.truffle.api.frame.FrameSlot;
15+
import com.oracle.truffle.api.frame.FrameSlotKind;
1216
import com.oracle.truffle.api.frame.VirtualFrame;
1317
import com.oracle.truffle.api.nodes.Node;
18+
19+
import org.jruby.runtime.Visibility;
1420
import org.jruby.truffle.runtime.RubyContext;
21+
import org.jruby.truffle.runtime.core.RubyModule;
1522
import org.jruby.truffle.runtime.core.RubyProc;
1623

1724
public class YieldDispatchHeadNode extends Node {
@@ -32,7 +39,18 @@ public Object dispatchWithModifiedBlock(VirtualFrame frame, RubyProc block, Ruby
3239
}
3340

3441
public Object dispatchWithModifiedSelf(VirtualFrame frame, RubyProc block, Object self, Object... argumentsObjects) {
35-
return dispatch.dispatchWithModifiedSelf(frame, block, self, argumentsObjects);
42+
// TODO: assumes this also changes the default definee.
43+
44+
FrameSlot slot = frame.getFrameDescriptor().findOrAddFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID, "dynamic visibility for def", FrameSlotKind.Object);
45+
Object oldVisibility = frame.getValue(slot);
46+
47+
try {
48+
frame.setObject(slot, Visibility.PUBLIC);
49+
50+
return dispatch.dispatchWithModifiedSelf(frame, block, self, argumentsObjects);
51+
} finally {
52+
frame.setObject(slot, oldVisibility);
53+
}
3654
}
3755

3856
public YieldDispatchNode getDispatch() {

core/src/main/java/org/jruby/truffle/translator/TranslatorEnvironment.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
import com.oracle.truffle.api.frame.FrameDescriptor;
1313
import com.oracle.truffle.api.frame.FrameSlot;
14+
import com.oracle.truffle.api.frame.FrameSlotKind;
1415
import com.oracle.truffle.api.source.SourceSection;
16+
1517
import org.jruby.truffle.nodes.RubyNode;
1618
import org.jruby.truffle.nodes.methods.locals.ReadLevelVariableNodeFactory;
1719
import org.jruby.truffle.nodes.methods.locals.ReadLocalVariableNodeFactory;
@@ -200,7 +202,7 @@ public boolean getNeverAssignInParentScope() {
200202
}
201203

202204
public void addMethodDeclarationSlots() {
203-
frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
205+
frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID, "lexical visibility for def", FrameSlotKind.Object);
204206
}
205207

206208
public SharedMethodInfo getSharedMethodInfo() {

spec/truffle/tags/language/def_tags.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ fails:A nested method definition creates a class method when evaluated in a clas
33
fails:A method definition inside an instance_eval creates a class method when the receiver is a class
44
fails:A method definition in an eval creates an instance method
55
fails:A method definition in an eval creates a class method
6-
fails(inherited):The def keyword within a closure looks outside the closure for the visibility
76
fails:A method definition in an eval creates a singleton method

0 commit comments

Comments
 (0)