Skip to content

Commit

Permalink
[Truffle] Store the visibility in the frame and walk the frames to fi…
Browse files Browse the repository at this point in the history
…nd it.
  • Loading branch information
eregon committed Jan 7, 2015
1 parent fda9948 commit 3e4f49c
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
Expand Up @@ -459,7 +459,7 @@ public ClassExecNode(ClassExecNode prev) {
public abstract Object executeClassEval(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block);

@Specialization
public Object classEval(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block) {
public Object classExec(VirtualFrame frame, RubyModule self, Object[] args, RubyProc block) {
notDesignedForCompilation();

// TODO: deal with args
Expand Down
Expand Up @@ -11,15 +11,21 @@

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotTypeException;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeUtil;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.RubyRootNode;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.methods.RubyMethod;
Expand Down Expand Up @@ -71,29 +77,39 @@ public RubyMethod executeMethod(VirtualFrame frame, MaterializedFrame declaratio
}

private Visibility getVisibility(VirtualFrame frame) {
notDesignedForCompilation();

if (ignoreLocalVisibility) {
return Visibility.PUBLIC;
} else if (name.equals("initialize") || name.equals("initialize_copy") || name.equals("initialize_clone") || name.equals("initialize_dup") || name.equals("respond_to_missing?")) {
return Visibility.PRIVATE;
} else {
final FrameSlot visibilitySlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);

if (visibilitySlot == null) {
return Visibility.PUBLIC;
} else {
Object visibilityObject;
// Ignore scopes who do not have a visibility slot.
Visibility currentFrameVisibility = findVisibility(frame);
if (currentFrameVisibility != null) {
return currentFrameVisibility;
}

try {
visibilityObject = frame.getObject(visibilitySlot);
} catch (FrameSlotTypeException e) {
throw new RuntimeException(e);
return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Visibility>() {
@Override
public Visibility visitFrame(FrameInstance frameInstance) {
Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY, true);
return findVisibility(frame);
}
});
}
}

if (visibilityObject instanceof Visibility) {
return (Visibility) visibilityObject;
} else {
return Visibility.PUBLIC;
}
private static Visibility findVisibility(Frame frame) {
FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
if (slot == null) {
return null;
} else {
Object visibilityObject = frame.getValue(slot);
if (visibilityObject instanceof Visibility) {
return (Visibility) visibilityObject;
} else {
return Visibility.PUBLIC;
}
}
}
Expand Down
Expand Up @@ -9,9 +9,16 @@
*/
package org.jruby.truffle.nodes.yield;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.core.RubyModule;
import org.jruby.truffle.runtime.core.RubyProc;

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

public Object dispatchWithModifiedSelf(VirtualFrame frame, RubyProc block, Object self, Object... argumentsObjects) {
return dispatch.dispatchWithModifiedSelf(frame, block, self, argumentsObjects);
// TODO: assumes this also changes the default definee.

FrameSlot slot = frame.getFrameDescriptor().findOrAddFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID, "dynamic visibility for def", FrameSlotKind.Object);
Object oldVisibility = frame.getValue(slot);

try {
frame.setObject(slot, Visibility.PUBLIC);

return dispatch.dispatchWithModifiedSelf(frame, block, self, argumentsObjects);
} finally {
frame.setObject(slot, oldVisibility);
}
}

public YieldDispatchNode getDispatch() {
Expand Down
Expand Up @@ -11,7 +11,9 @@

import com.oracle.truffle.api.frame.FrameDescriptor;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.FrameSlotKind;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.methods.locals.ReadLevelVariableNodeFactory;
import org.jruby.truffle.nodes.methods.locals.ReadLocalVariableNodeFactory;
Expand Down Expand Up @@ -200,7 +202,7 @@ public boolean getNeverAssignInParentScope() {
}

public void addMethodDeclarationSlots() {
frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID);
frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID, "lexical visibility for def", FrameSlotKind.Object);
}

public SharedMethodInfo getSharedMethodInfo() {
Expand Down
1 change: 0 additions & 1 deletion spec/truffle/tags/language/def_tags.txt
Expand Up @@ -3,5 +3,4 @@ fails:A nested method definition creates a class method when evaluated in a clas
fails:A method definition inside an instance_eval creates a class method when the receiver is a class
fails:A method definition in an eval creates an instance method
fails:A method definition in an eval creates a class method
fails(inherited):The def keyword within a closure looks outside the closure for the visibility
fails:A method definition in an eval creates a singleton method

0 comments on commit 3e4f49c

Please sign in to comment.