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: 575275f7e80c
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: fa42a0209eb5
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Oct 27, 2014

  1. Copy the full SHA
    45a2a56 View commit details
  2. [Truffle] Have a try at implementing Proc#binding.

    * We therefore need a declaration frame for every block
      as it is needed retrospectively when calling Proc#binding.
    eregon committed Oct 27, 2014
    Copy the full SHA
    fa42a02 View commit details
59 changes: 41 additions & 18 deletions core/src/main/java/org/jruby/truffle/nodes/core/ProcNodes.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.source.*;
import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.frame.*;
@@ -19,45 +20,67 @@
@CoreClass(name = "Proc")
public abstract class ProcNodes {

@CoreMethod(names = {"call", "[]"}, argumentsAsArray = true)
public abstract static class CallNode extends CoreMethodNode {

@Child protected YieldDispatchHeadNode yieldNode;
@CoreMethod(names = "initialize", needsBlock = true)
public abstract static class InitializeNode extends CoreMethodNode {

public CallNode(RubyContext context, SourceSection sourceSection) {
public InitializeNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
yieldNode = new YieldDispatchHeadNode(context);
}

public CallNode(CallNode prev) {
public InitializeNode(InitializeNode prev) {
super(prev);
yieldNode = prev.yieldNode;
}

@Specialization
public Object call(VirtualFrame frame, RubyProc proc, Object[] args) {
return yieldNode.dispatch(frame, proc, args);
public RubyNilClass initialize(RubyProc proc, RubyProc block) {
proc.initialize(block.getSharedMethodInfo(), block.getCallTargetForMethods(), block.getCallTargetForMethods(),
block.getDeclarationFrame(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());

return getContext().getCoreLibrary().getNilObject();
}

}

@CoreMethod(names = "initialize", needsBlock = true)
public abstract static class InitializeNode extends CoreMethodNode {
@CoreMethod(names = "binding")
public abstract static class BindingNode extends CoreMethodNode {

public InitializeNode(RubyContext context, SourceSection sourceSection) {
public BindingNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public InitializeNode(InitializeNode prev) {
public BindingNode(BindingNode prev) {
super(prev);
}

@Specialization
public RubyNilClass initialize(RubyProc proc, RubyProc block) {
proc.initialize(block.getSharedMethodInfo(), block.getCallTargetForMethods(), block.getCallTargetForMethods(),
block.getDeclarationFrame(), block.getSelfCapturedInScope(), block.getBlockCapturedInScope());
public RubyBinding binding(RubyProc proc) {
final MaterializedFrame frame = proc.getDeclarationFrame();

return getContext().getCoreLibrary().getNilObject();
return new RubyBinding(getContext().getCoreLibrary().getBindingClass(),
RubyArguments.getSelf(frame.getArguments()),
frame);
}

}

@CoreMethod(names = {"call", "[]"}, argumentsAsArray = true)
public abstract static class CallNode extends CoreMethodNode {

@Child protected YieldDispatchHeadNode yieldNode;

public CallNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
yieldNode = new YieldDispatchHeadNode(context);
}

public CallNode(CallNode prev) {
super(prev);
yieldNode = prev.yieldNode;
}

@Specialization
public Object call(VirtualFrame frame, RubyProc proc, Object[] args) {
return yieldNode.dispatch(frame, proc, args);
}

}
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.FrameSlot;
import org.jruby.runtime.Visibility;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.*;
import org.jruby.truffle.runtime.core.*;
@@ -254,7 +255,10 @@ public void visitFrame(Frame frame, ObjectGraphVisitor visitor) {
}

for (FrameSlot slot : frame.getFrameDescriptor().getSlots()) {
context.getCoreLibrary().box(frame.getValue(slot)).visitObjectGraph(visitor);
Object value = frame.getValue(slot);
if (!(value instanceof Visibility)) { // TODO(cs): Better condition for hidden local variables
context.getCoreLibrary().box(value).visitObjectGraph(visitor);
}
}
}

Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ public class TranslatorEnvironment {
private final boolean neverAssignInParentScope;

protected final TranslatorEnvironment parent;
private boolean needsDeclarationFrame = false;
private boolean needsDeclarationFrame = true;
private final SharedMethodInfo sharedMethodInfo;

private final String namedMethodName;
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/proc/binding_tags.txt

This file was deleted.