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

Commits on Oct 7, 2016

  1. Copy the full SHA
    0bb8863 View commit details
  2. Copy the full SHA
    0f3030b View commit details
  3. Copy the full SHA
    e67238e View commit details
75 changes: 20 additions & 55 deletions truffle/src/main/java/org/jruby/truffle/core/MathNodes.java
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
*/
package org.jruby.truffle.core;

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;
@@ -51,14 +52,11 @@
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.Primitive;
import org.jruby.truffle.builtins.PrimitiveArrayArgumentsNode;
import org.jruby.truffle.core.cast.ToFNode;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.dispatch.MissingBehavior;
import org.jruby.truffle.language.objects.IsANode;
import org.jruby.truffle.language.objects.IsANodeGen;
import org.jruby.truffle.util.DoubleUtils;

@CoreClass("Math")
public abstract class MathNodes {
@@ -282,34 +280,8 @@ protected double doFunction(double a) {

}

@CoreMethod(names = "frexp", isModuleFunction = true, required = 1)
public abstract static class FrExpNode extends CoreMethodArrayArgumentsNode {

private final BranchProfile errorProfile = BranchProfile.create();

@Child private IsANode isANode;
@Child private CallDispatchHeadNode floatNode;

public FrExpNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
isANode = IsANodeGen.create(context, sourceSection, null, null);
floatNode = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.RETURN_MISSING);
}

@Specialization
public DynamicObject frexp(int a) {
return frexp((double) a);
}

@Specialization
public DynamicObject frexp(long a) {
return frexp((double) a);
}

@Specialization(guards = "isRubyBignum(a)")
public DynamicObject frexp(DynamicObject a) {
return frexp(Layouts.BIGNUM.getValue(a).doubleValue());
}
@Primitive(name = "math_frexp", needsSelf = false)
public abstract static class FrExpNode extends PrimitiveArrayArgumentsNode {

@Specialization
public DynamicObject frexp(double a) {
@@ -335,13 +307,8 @@ public DynamicObject frexp(double a) {
}

@Fallback
public DynamicObject frexp(VirtualFrame frame, Object a) {
if (isANode.executeIsA(a, coreLibrary().getNumericClass())) {
return frexp(floatNode.callFloat(frame, a, "to_f", null));
} else {
errorProfile.enter();
throw new RaiseException(coreExceptions().typeErrorCantConvertInto(a, "Float", this));
}
public Object frexp(Object a) {
return FAILURE;
}

}
@@ -422,14 +389,14 @@ public Object ldexp(Object a, Object b) {
public abstract static class LGammaNode extends CoreMethodArrayArgumentsNode {

@Child private IsANode isANode;
@Child private CallDispatchHeadNode floatNode;
@Child private ToFNode toFNode;

private final BranchProfile exceptionProfile = BranchProfile.create();

public LGammaNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
isANode = IsANodeGen.create(context, sourceSection, null, null);
floatNode = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.RETURN_MISSING);
toFNode = ToFNode.create();
}

@Specialization
@@ -466,7 +433,7 @@ public DynamicObject lgamma(VirtualFrame frame, Object a) {
throw new RaiseException(coreExceptions().typeErrorCantConvertInto(a, "Float", this));
}

return lgamma(floatNode.callFloat(frame, a, "to_f", null));
return lgamma(toFNode.doDouble(frame, a));
}

}
@@ -495,13 +462,13 @@ public double function(double a, NotProvided b) {
}

@Specialization
public double function(VirtualFrame frame, Object a, NotProvided b) {
public double function(VirtualFrame frame, Object a, NotProvided b,
@Cached("create()") ToFNode toFNode) {
if (!isANode.executeIsA(a, coreLibrary().getNumericClass())) {
exceptionProfile.enter();
throw new RaiseException(coreExceptions().typeErrorCantConvertInto(a, "Float", this));
}

return doFunction(floatANode.callFloat(frame, a, "to_f", null));
return doFunction(toFNode.doDouble(frame, a));
}

private double doFunction(double a) {
@@ -610,7 +577,7 @@ protected double doFunction(double a) {
protected abstract static class SimpleMonadicMathNode extends CoreMethodArrayArgumentsNode {

@Child private IsANode isANode;
@Child private CallDispatchHeadNode floatNode;
@Child private ToFNode toFNode;

protected final BranchProfile exceptionProfile = BranchProfile.create();

@@ -621,7 +588,7 @@ protected SimpleMonadicMathNode() {
protected SimpleMonadicMathNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
isANode = IsANodeGen.create(context, sourceSection, null, null);
floatNode = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.RETURN_MISSING);
toFNode = ToFNode.create();
}

// TODO: why can't we leave this abstract?
@@ -657,16 +624,16 @@ public double function(VirtualFrame frame, Object a) {
throw new RaiseException(coreExceptions().typeErrorCantConvertInto(a, "Float", this));
}

return doFunction(floatNode.callFloat(frame, a, "to_f", null));
return doFunction(toFNode.doDouble(frame, a));
}

}

protected abstract static class SimpleDyadicMathNode extends CoreMethodArrayArgumentsNode {

@Child protected IsANode isANode;
@Child protected CallDispatchHeadNode floatANode;
@Child protected CallDispatchHeadNode floatBNode;
@Child protected ToFNode floatANode;
@Child protected ToFNode floatBNode;

protected final BranchProfile exceptionProfile = BranchProfile.create();

@@ -677,8 +644,8 @@ protected SimpleDyadicMathNode() {
protected SimpleDyadicMathNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
isANode = IsANodeGen.create(context, sourceSection, null, null);
floatANode = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.RETURN_MISSING);
floatBNode = DispatchHeadNodeFactory.createMethodCall(context, MissingBehavior.RETURN_MISSING);
floatANode = ToFNode.create();
floatBNode = ToFNode.create();
}

// TODO: why can't we leave this abstract?
@@ -775,9 +742,7 @@ public double function(VirtualFrame frame, Object a, Object b) {
throw new RaiseException(coreExceptions().typeErrorCantConvertInto(a, "Float", this));
}

return doFunction(
floatANode.callFloat(frame, a, "to_f", null),
floatBNode.callFloat(frame, b, "to_f", null));
return doFunction(floatANode.doDouble(frame, a), floatBNode.doDouble(frame, b));
}

}
Original file line number Diff line number Diff line change
@@ -32,8 +32,8 @@ public abstract class ToFNode extends RubyNode {

private final BranchProfile errorProfile = BranchProfile.create();

public ToFNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
public static ToFNode create() {
return ToFNodeGen.create(null);
}

public double doDouble(VirtualFrame frame, Object value) {
Original file line number Diff line number Diff line change
@@ -11,17 +11,13 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.cast.ToFNode;
import org.jruby.truffle.core.cast.ToFNodeGen;
import org.jruby.truffle.core.format.FormatNode;

@NodeChildren({
@NodeChild(value = "value", type = FormatNode.class),
})
@NodeChild(value = "value", type = FormatNode.class)
public abstract class ToDoubleWithCoercionNode extends FormatNode {

@Child private ToFNode toFNode;
@@ -34,7 +30,7 @@ public ToDoubleWithCoercionNode(RubyContext context) {
public Object toDouble(VirtualFrame frame, Object value) {
if (toFNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
toFNode = insert(ToFNodeGen.create(getContext(), null, null));
toFNode = insert(ToFNode.create());
}

return toFNode.doDouble(frame, value);
Original file line number Diff line number Diff line change
@@ -12,18 +12,14 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.cast.BooleanCastNode;
import org.jruby.truffle.core.cast.BooleanCastNodeGen;
import org.jruby.truffle.language.control.RaiseException;

public class CallDispatchHeadNode extends DispatchHeadNode {

@Child private BooleanCastNode booleanCastNode;

private final BranchProfile errorProfile = BranchProfile.create();

public static CallDispatchHeadNode createMethodCall() {
return new CallDispatchHeadNode(
null,
@@ -69,24 +65,4 @@ public boolean callBoolean(
dispatch(frame, receiverObject, methodName, blockObject, argumentsObjects));
}

public double callFloat(
VirtualFrame frame,
Object receiverObject,
Object methodName,
DynamicObject blockObject,
Object... argumentsObjects) {
final Object value = dispatch(frame, receiverObject, methodName, blockObject, argumentsObjects);

if (value instanceof Double) {
return (double) value;
}

errorProfile.enter();
if (value == DispatchNode.MISSING) {
throw new RaiseException(context.getCoreExceptions().typeErrorCantConvertInto(receiverObject, "Float", this));
} else {
throw new RaiseException(context.getCoreExceptions().typeErrorCantConvertTo(receiverObject, "Float", (String) methodName, value, this));
}
}

}
6 changes: 6 additions & 0 deletions truffle/src/main/ruby/core/math.rb
Original file line number Diff line number Diff line change
@@ -14,6 +14,12 @@ module Math
DomainError = Errno::EDOM

module_function

def frexp(x)
Truffle.primitive :math_frexp
frexp Rubinius::Type.coerce_to_float(x)
end

def ldexp(fraction, exponent)
Truffle.primitive :math_ldexp
raise RangeError, "float NaN out of range of integer" if Float === exponent and exponent.nan?