Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a8563aa33f39
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 691e5771f096
Choose a head ref
  • 9 commits
  • 24 files changed
  • 1 contributor

Commits on Oct 2, 2015

  1. [Truffle] Passing spec.

    eregon committed Oct 2, 2015
    Copy the full SHA
    686c05d View commit details
  2. Copy the full SHA
    c1bef16 View commit details
  3. Clarify private spec

    eregon committed Oct 2, 2015
    Copy the full SHA
    6281afe View commit details
  4. Copy the full SHA
    bc7ca1f View commit details
  5. Add new spec tags.

    eregon committed Oct 2, 2015
    Copy the full SHA
    68cfa09 View commit details
  6. Copy the full SHA
    6cbce97 View commit details
  7. Copy the full SHA
    e089f73 View commit details
  8. Copy the full SHA
    b30ac42 View commit details
  9. Copy the full SHA
    691e577 View commit details
Showing with 122 additions and 265 deletions.
  1. +14 −0 spec/ruby/core/module/shared/set_visibility.rb
  2. +3 −1 spec/ruby/language/fixtures/private.rb
  3. +5 −1 spec/ruby/language/private_spec.rb
  4. +1 −0 spec/tags/ruby/core/module/private_tags.txt
  5. +1 −0 spec/tags/ruby/core/module/protected_tags.txt
  6. +0 −1 spec/truffle/tags/core/kernel/public_method_tags.txt
  7. +0 −2 spec/truffle/tags/core/module/private_tags.txt
  8. +0 −2 spec/truffle/tags/core/module/protected_tags.txt
  9. +0 −2 spec/truffle/tags/core/module/public_tags.txt
  10. +4 −0 truffle/src/main/java/org/jruby/truffle/nodes/RubyRootNode.java
  11. +1 −7 truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
  12. +3 −25 truffle/src/main/java/org/jruby/truffle/nodes/core/ModuleNodes.java
  13. +9 −33 truffle/src/main/java/org/jruby/truffle/nodes/methods/AddMethodNode.java
  14. +24 −10 truffle/src/main/java/org/jruby/truffle/nodes/methods/DeclarationContext.java
  15. +0 −52 truffle/src/main/java/org/jruby/truffle/nodes/methods/SetMethodDeclarationContext.java
  16. +5 −34 truffle/src/main/java/org/jruby/truffle/nodes/yield/YieldDispatchHeadNode.java
  17. +3 −2 truffle/src/main/java/org/jruby/truffle/runtime/RubyCallStack.java
  18. +31 −44 truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
  19. +3 −2 truffle/src/main/java/org/jruby/truffle/runtime/core/CoreLibrary.java
  20. +2 −4 truffle/src/main/java/org/jruby/truffle/runtime/subsystems/SimpleShell.java
  21. +9 −6 truffle/src/main/java/org/jruby/truffle/translator/BodyTranslator.java
  22. +1 −5 truffle/src/main/java/org/jruby/truffle/translator/ModuleTranslator.java
  23. +0 −25 truffle/src/main/java/org/jruby/truffle/translator/NodeWrapper.java
  24. +3 −7 truffle/src/main/java/org/jruby/truffle/translator/TranslatorDriver.java
14 changes: 14 additions & 0 deletions spec/ruby/core/module/shared/set_visibility.rb
Original file line number Diff line number Diff line change
@@ -119,5 +119,19 @@ def test1() end

mod.should send(:"have_#{@method}_instance_method", :test1, false)
end

describe "within a closure" do
it "sets the visibility outside the closure" do
visibility = @method
mod = Module.new {
1.times {
send visibility
}
def test1() end
}

mod.should send(:"have_#{@method}_instance_method", :test1, false)
end
end
end
end
4 changes: 3 additions & 1 deletion spec/ruby/language/fixtures/private.rb
Original file line number Diff line number Diff line change
@@ -16,6 +16,9 @@ def foo
end

private

def self.public_defs_method; 0; end

class C
def baz
"baz"
@@ -27,7 +30,6 @@ def public_class_method1; 1; end
private
def private_class_method1; 1; end
end
def self.public_class_method2; 2; end

def bar
"bar"
6 changes: 5 additions & 1 deletion spec/ruby/language/private_spec.rb
Original file line number Diff line number Diff line change
@@ -12,12 +12,16 @@
lambda { b.bar }.should raise_error(NoMethodError)
end

# def expr.meth() methods are always public
it "has no effect on def expr.meth() methods" do
Private::B.public_defs_method.should == 0
end

it "is overridden when a new class is opened" do
c = Private::B::C.new
c.methods.should include(:baz)
c.baz
Private::B.public_class_method1.should == 1
Private::B.public_class_method2.should == 2
lambda { Private::B.private_class_method1 }.should raise_error(NoMethodError)
end

1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/private_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
fails:Module#private without arguments does not affect method definitions when itself is inside an eval and method definitions are outside
fails:Module#private without arguments within a closure sets the visibility outside the closure
1 change: 1 addition & 0 deletions spec/tags/ruby/core/module/protected_tags.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
fails:Module#protected without arguments does not affect method definitions when itself is inside an eval and method definitions are outside
fails:Module#protected without arguments within a closure sets the visibility outside the closure
1 change: 0 additions & 1 deletion spec/truffle/tags/core/kernel/public_method_tags.txt
Original file line number Diff line number Diff line change
@@ -2,4 +2,3 @@ fails:Kernel#public_method returns a method object for a valid method
fails:Kernel#public_method returns a method object for a valid singleton method
fails:Kernel#public_method returns a method object if we repond_to_missing? method
fails:Kernel#public_method changes the method called for super on a target aliased method
fails:Kernel#public_method raises a NameError if we only repond_to_missing? method, true
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/module/private_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/module/protected_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/module/public_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
fails:Module#public on a superclass method calls the redefined method
fails:Module#public without arguments affects evaled method definitions when itself is outside the eval
fails:Module#public without arguments affects normally if itself and following method definitions are inside a eval
Original file line number Diff line number Diff line change
@@ -45,6 +45,10 @@ public RubyRootNode(RubyContext context, SourceSection sourceSection, FrameDescr
this.needsDeclarationFrame = needsDeclarationFrame;
}

public RubyRootNode withBody(RubyNode body) {
return new RubyRootNode(context, getSourceSection(), getFrameDescriptor(), sharedMethodInfo, body, needsDeclarationFrame);
}

@Override
public boolean isCloningAllowed() {
return true;
Original file line number Diff line number Diff line change
@@ -76,7 +76,6 @@
import org.jruby.truffle.runtime.loader.FeatureLoader;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingAction;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.truffle.translator.TranslatorDriver.ParserContext;
import org.jruby.util.ByteList;
@@ -676,12 +675,7 @@ protected RootNodeWrapper compileSource(VirtualFrame frame, DynamicObject source

final TranslatorDriver translator = new TranslatorDriver(getContext());

return new RootNodeWrapper(translator.parse(getContext(), source, UTF8Encoding.INSTANCE, ParserContext.EVAL, parentFrame, true, this, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return node; // return new SetMethodDeclarationContext(node.getContext(), node.getSourceSection(), Visibility.PRIVATE, "simple eval", node);
}
}));
return new RootNodeWrapper(translator.parse(getContext(), source, UTF8Encoding.INSTANCE, ParserContext.EVAL, parentFrame, true, this));
}

protected boolean parseDependsOnDeclarationFrame(RootNodeWrapper rootNode) {
Original file line number Diff line number Diff line change
@@ -47,7 +47,6 @@
import org.jruby.truffle.nodes.methods.CanBindMethodToModuleNode;
import org.jruby.truffle.nodes.methods.CanBindMethodToModuleNodeGen;
import org.jruby.truffle.nodes.methods.DeclarationContext;
import org.jruby.truffle.nodes.methods.SetMethodDeclarationContext;
import org.jruby.truffle.nodes.objects.*;
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
import org.jruby.truffle.runtime.*;
@@ -60,8 +59,6 @@
import org.jruby.truffle.runtime.methods.Arity;
import org.jruby.truffle.runtime.methods.InternalMethod;
import org.jruby.truffle.runtime.methods.SharedMethodInfo;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.truffle.translator.TranslatorDriver.ParserContext;
import org.jruby.util.IdUtil;
import org.jruby.util.StringSupport;
@@ -74,12 +71,6 @@
@CoreClass(name = "Module")
public abstract class ModuleNodes {

/**
* The slot within a module definition method frame where we store the implicit state that is
* the current visibility for new methods.
*/
public static final Object VISIBILITY_FRAME_SLOT_ID = new Object();

public static DynamicObject createRubyModule(RubyContext context, DynamicObject selfClass, DynamicObject lexicalParent, String name, Node currentNode) {
final ModuleFields model = new ModuleFields(context, lexicalParent, name);
final DynamicObject module = Layouts.MODULE.createModule(Layouts.CLASS.getInstanceFactory(selfClass), model);
@@ -401,7 +392,7 @@ public DynamicObject generateAccessor(VirtualFrame frame, DynamicObject module,
CompilerDirectives.transferToInterpreter();
final FrameInstance callerFrame = RubyCallStack.getCallerFrame(getContext());
final SourceSection sourceSection = callerFrame.getCallNode().getEncapsulatingSourceSection();
final Visibility visibility = AddMethodNode.getVisibility(callerFrame.getFrame(FrameAccess.READ_ONLY, true));
final Visibility visibility = DeclarationContext.findVisibility(callerFrame.getFrame(FrameAccess.READ_ONLY, true));
final Arity arity = isGetter ? Arity.NO_ARGUMENTS : Arity.ONE_REQUIRED;
final String ivar = "@" + name;
final String accessorName = isGetter ? name : name + "=";
@@ -654,12 +645,7 @@ private Object classEvalSource(DynamicObject module, DynamicObject code, String
CompilerDirectives.transferToInterpreter();
Source source = Source.fromText(code.toString(), file);

return getContext().execute(source, encoding, ParserContext.MODULE, module, callerFrame, true, DeclarationContext.CLASS_EVAL, this, new NodeWrapper() {
@Override
public RubyNode wrap(RubyNode node) {
return new SetMethodDeclarationContext(node.getContext(), node.getSourceSection(), Visibility.PUBLIC, "class_eval", node);
}
});
return getContext().parseAndExecute(source, encoding, ParserContext.MODULE, module, callerFrame, true, DeclarationContext.CLASS_EVAL, this);
}

@Specialization(guards = "isRubyProc(block)")
@@ -1936,16 +1922,8 @@ public DynamicObject setVisibility(VirtualFrame frame, DynamicObject module, Obj
}

private void setCurrentVisibility(Visibility visibility) {
CompilerDirectives.transferToInterpreter();

final Frame callerFrame = RubyCallStack.getCallerFrame(getContext()).getFrame(FrameInstance.FrameAccess.READ_WRITE, true);
assert callerFrame != null;
assert callerFrame.getFrameDescriptor() != null;

final FrameSlot visibilitySlot = callerFrame.getFrameDescriptor().findOrAddFrameSlot(
VISIBILITY_FRAME_SLOT_ID, "visibility for frame", FrameSlotKind.Object);

callerFrame.setObject(visibilitySlot, visibility);
DeclarationContext.changeVisibility(callerFrame, visibility);
}

}
Original file line number Diff line number Diff line change
@@ -11,31 +11,31 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.FrameSlot;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;

import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.ModuleNodes;
import org.jruby.truffle.nodes.objects.SingletonClassNode;
import org.jruby.truffle.nodes.objects.SingletonClassNodeGen;
import org.jruby.truffle.runtime.ModuleOperations;
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.layouts.Layouts;
import org.jruby.truffle.runtime.methods.InternalMethod;

public class AddMethodNode extends RubyNode {

private final boolean isDefs; // def expr.meth()

@Child private RubyNode receiver;
@Child private MethodDefinitionNode methodNode;
@Child private SingletonClassNode singletonClassNode;

public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiver, MethodDefinitionNode method) {
public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiver, MethodDefinitionNode method, boolean isDefs) {
super(context, section);
this.isDefs = isDefs;
this.receiver = receiver;
this.methodNode = method;
this.singletonClassNode = SingletonClassNodeGen.create(context, section, null);
@@ -65,37 +65,13 @@ public DynamicObject execute(VirtualFrame frame) {
return getSymbol(method.getName());
}

private static Visibility getVisibility(Frame frame, String name) {
if (ModuleOperations.isMethodPrivateFromName(name)) {
private Visibility getVisibility(Frame frame, String name) {
if (isDefs) {
return Visibility.PUBLIC;
} else if (ModuleOperations.isMethodPrivateFromName(name)) {
return Visibility.PRIVATE;
} else {
return getVisibility(frame);
}
}

public static Visibility getVisibility(Frame frame) {
while (frame != null) {
Visibility visibility = findVisibility(frame);
if (visibility != null) {
return visibility;
}
frame = RubyArguments.getDeclarationFrame(frame.getArguments());
}

throw new UnsupportedOperationException("No declaration frame with visibility found");
}

private static Visibility findVisibility(Frame frame) {
FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(ModuleNodes.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;
}
return DeclarationContext.findVisibility(frame);
}
}
}
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import org.jruby.truffle.runtime.RubyArguments;
import org.jruby.truffle.runtime.RubyContext;

import com.oracle.truffle.api.frame.Frame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;

@@ -41,15 +42,28 @@ public DeclarationContext(Visibility visibility, DefaultDefinee defaultDefinee)
this.defaultDefinee = defaultDefinee;
}

public Visibility getVisibility() {
return visibility;
private static Frame lookupVisibility(Frame frame) {
while (frame != null) {
final Visibility visibility = RubyArguments.getDeclarationContext(frame.getArguments()).visibility;
if (visibility != null) {
return frame;
}
frame = RubyArguments.getDeclarationFrame(frame.getArguments());
}
throw new UnsupportedOperationException("No declaration frame with visibility found");
}

public static Visibility findVisibility(Frame frame) {
final Frame visibilityFrame = lookupVisibility(frame);
return RubyArguments.getDeclarationContext(visibilityFrame.getArguments()).visibility;
}

public DeclarationContext withVisibility(Visibility visibility) {
if (visibility == this.visibility) {
return this;
} else {
return new DeclarationContext(visibility, this.defaultDefinee);
public static void changeVisibility(Frame frame, Visibility newVisibility) {
final Frame visibilityFrame = lookupVisibility(frame);
final DeclarationContext oldDeclarationContext = RubyArguments.getDeclarationContext(visibilityFrame.getArguments());
if (newVisibility != oldDeclarationContext.visibility) {
final DeclarationContext newDeclarationContext = new DeclarationContext(newVisibility, oldDeclarationContext.defaultDefinee);
RubyArguments.setDeclarationContext(visibilityFrame.getArguments(), newDeclarationContext);
}
}

@@ -68,9 +82,9 @@ public DynamicObject getModuleToDefineMethods(VirtualFrame frame, RubyContext co
}

public static final DeclarationContext MODULE = new DeclarationContext(Visibility.PUBLIC, DefaultDefinee.LEXICAL_SCOPE);
public static final DeclarationContext METHOD = MODULE;
public static final DeclarationContext BLOCK = METHOD;
public static final DeclarationContext TOP_LEVEL = METHOD;
public static final DeclarationContext METHOD = new DeclarationContext(null, DefaultDefinee.LEXICAL_SCOPE);
public static final DeclarationContext BLOCK = new DeclarationContext(null, DefaultDefinee.LEXICAL_SCOPE);
public static final DeclarationContext TOP_LEVEL = new DeclarationContext(Visibility.PRIVATE, DefaultDefinee.LEXICAL_SCOPE);
public static final DeclarationContext INSTANCE_EVAL = new DeclarationContext(Visibility.PUBLIC, DefaultDefinee.SINGLETON_CLASS);
public static final DeclarationContext CLASS_EVAL = new DeclarationContext(Visibility.PUBLIC, DefaultDefinee.SELF);

This file was deleted.

Loading