Skip to content

Commit

Permalink
Showing 2 changed files with 61 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -11,10 +11,13 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.methods.UnsupportedOperationBehavior;
import org.jruby.truffle.runtime.NotProvided;
import org.jruby.truffle.runtime.RubyContext;
@@ -28,6 +31,8 @@ public abstract class IntegerNodes {
@CoreMethod(names = "downto", needsBlock = true, required = 1, returnsEnumeratorIfNoBlock = true, unsupportedOperationBehavior = UnsupportedOperationBehavior.ARGUMENT_ERROR)
public abstract static class DownToNode extends YieldingCoreMethodNode {

@Child private CallDispatchHeadNode downtoInternalCall;

public DownToNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -53,6 +58,11 @@ public Object downto(VirtualFrame frame, int from, int to, DynamicObject block)
return nil();
}

@Specialization(guards = "isRubyProc(block)")
public Object downto(VirtualFrame frame, int from, double to, DynamicObject block) {
return downto(frame, from, (int) Math.ceil(to), block);
}

@Specialization(guards = "isRubyProc(block)")
public Object downto(VirtualFrame frame, long from, long to, DynamicObject block) {
// TODO BJF 22-Apr-2015 how to handle reportLoopCount(long)
@@ -76,8 +86,27 @@ public Object downto(VirtualFrame frame, long from, long to, DynamicObject block
}

@Specialization(guards = "isRubyProc(block)")
public Object downto(VirtualFrame frame, int from, double to, DynamicObject block) {
return downto(frame, from, (int) Math.ceil(to), block);
public Object downto(VirtualFrame frame, long from, double to, DynamicObject block) {
return downto(frame, from, (long) Math.ceil(to), block);
}

@Specialization(guards = "isDynamicObject(from) || isDynamicObject(to)")
public Object downto(VirtualFrame frame, Object from, Object to, DynamicObject block) {
return downtoInternal(frame, from, to, block);
}

@Specialization
public Object downto(VirtualFrame frame, Object from, Object to, NotProvided block) {
return downtoInternal(frame, from, to, null);
}

This comment has been minimized.

Copy link
@eregon

eregon Sep 17, 2015

Member

Is returnsEnumeratorIfNoBlock not working here?

This comment has been minimized.

Copy link
@pitr-ch

pitr-ch Sep 17, 2015

Author Member

Most probably it is working, I've missed it. Fixing.

This comment has been minimized.

Copy link
@pitr-ch

pitr-ch Sep 17, 2015

Author Member

fixed in 0a32080


private Object downtoInternal(VirtualFrame frame, Object from, Object to, DynamicObject block) {
if (downtoInternalCall == null) {
CompilerDirectives.transferToInterpreter();
downtoInternalCall = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

return downtoInternalCall.call(frame, from, "downto_internal", block, to);
}

}
@@ -147,7 +176,7 @@ public Object times(VirtualFrame frame, long n, DynamicObject block) {

@Specialization(guards = "isRubyBignum(n)")
public Object times(VirtualFrame frame, DynamicObject n, DynamicObject block,
@Cached("create(getContext(), getSourceSection())") FixnumOrBignumNode fixnumOrBignumNode) {
@Cached("create(getContext(), getSourceSection())") FixnumOrBignumNode fixnumOrBignumNode) {

for (BigInteger i = BigInteger.ZERO; i.compareTo(Layouts.BIGNUM.getValue(n)) < 0; i = i.add(BigInteger.ONE)) {
yield(frame, block, fixnumOrBignumNode.fixnumOrBignum(i));
@@ -158,7 +187,7 @@ public Object times(VirtualFrame frame, DynamicObject n, DynamicObject block,

}

@CoreMethod(names = {"to_i", "to_int"})
@CoreMethod(names = { "to_i", "to_int" })
public abstract static class ToINode extends CoreMethodArrayArgumentsNode {

public ToINode(RubyContext context, SourceSection sourceSection) {
@@ -185,6 +214,8 @@ public DynamicObject toI(DynamicObject n) {
@CoreMethod(names = "upto", needsBlock = true, required = 1, returnsEnumeratorIfNoBlock = true, unsupportedOperationBehavior = UnsupportedOperationBehavior.ARGUMENT_ERROR)
public abstract static class UpToNode extends YieldingCoreMethodNode {

@Child private CallDispatchHeadNode uptoInternalCall;

public UpToNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -236,6 +267,30 @@ public Object upto(VirtualFrame frame, long from, long to, DynamicObject block)
return nil();
}

@Specialization(guards = "isRubyProc(block)")
public Object upto(VirtualFrame frame, long from, double to, DynamicObject block) {
return upto(frame, from, (long) Math.ceil(to), block);
}

@Specialization(guards = "isDynamicObject(from) || isDynamicObject(to)")
public Object upto(VirtualFrame frame, Object from, Object to, DynamicObject block) {
return uptoInternal(frame, from, to, block);
}

@Specialization
public Object upto(VirtualFrame frame, Object from, Object to, NotProvided block) {
return uptoInternal(frame, from, to, null);
}

private Object uptoInternal(VirtualFrame frame, Object from, Object to, DynamicObject block) {
if (uptoInternalCall == null) {
CompilerDirectives.transferToInterpreter();
uptoInternalCall = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

return uptoInternalCall.call(frame, from, "upto_internal", block, to);
}

}

}
Original file line number Diff line number Diff line change
@@ -89,6 +89,8 @@ public RubyNode visitDefnNode(org.jruby.ast.DefnNode node) {
rubiniusMethodRename = methodName.equals("round");
} else if (sourceSection.getSource().getPath().equals(context.getCoreLibrary().getCoreLoadPath() + "/core/rubinius/common/range.rb")) {
rubiniusMethodRename = methodName.equals("each") || methodName.equals("step") || methodName.equals("to_a");
} else if (sourceSection.getSource().getPath().equals(context.getCoreLibrary().getCoreLoadPath() + "/core/rubinius/common/integer.rb")) {
rubiniusMethodRename = methodName.equals("downto") || methodName.equals("upto");
}

if (rubiniusMethodRename) {

0 comments on commit c33cfd1

Please sign in to comment.