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

Commits on Feb 4, 2015

  1. [Truffle] Let CoreLibrary do the error formatting.

    * So callers do not need to know these details.
    eregon committed Feb 4, 2015
    Copy the full SHA
    82b183b View commit details
  2. Copy the full SHA
    955703b View commit details
  3. Copy the full SHA
    96e4133 View commit details
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.nodes.cast;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.KernelNodes;
import org.jruby.truffle.nodes.core.KernelNodesFactory;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.nodes.dispatch.MissingBehavior;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyBasicObject;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

/**
* Casts a value into a Ruby Float (double).
*/
@NodeChild(value = "child", type = RubyNode.class)
public abstract class NumericToFloatNode extends RubyNode {

@Child private KernelNodes.IsANode isANode;
@Child CallDispatchHeadNode toFloatCallNode;

private final String method;

public NumericToFloatNode(RubyContext context, SourceSection sourceSection, String method) {
super(context, sourceSection);
isANode = KernelNodesFactory.IsANodeFactory.create(context, sourceSection, new RubyNode[] { null, null });
this.method = method;
}

public NumericToFloatNode(NumericToFloatNode prev) {
super(prev.getContext(), prev.getSourceSection());
isANode = prev.isANode;
method = prev.method;
}

public abstract double executeFloat(VirtualFrame frame, RubyBasicObject value);

private Object callToFloat(VirtualFrame frame, RubyBasicObject value) {
if (toFloatCallNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
toFloatCallNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext(), MissingBehavior.RETURN_MISSING));
}
return toFloatCallNode.call(frame, value, method, null);
}

@Specialization(guards = "isNumeric")
protected double castNumeric(VirtualFrame frame, RubyBasicObject value) {
final Object result = callToFloat(frame, value);

if (result instanceof Double) {
return (double) result;
} else {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertTo(
value, getContext().getCoreLibrary().getFloatClass(), method, result, this));
}
}

@Fallback
protected double fallback(Object value) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
value, getContext().getCoreLibrary().getFloatClass(), this));
}

protected boolean isNumeric(VirtualFrame frame, Object value) {
return isANode.executeIsA(frame, value, getContext().getCoreLibrary().getNumericClass());
}

}
Original file line number Diff line number Diff line change
@@ -112,11 +112,7 @@ public RubyArray splat(VirtualFrame frame, Object object) {
return RubyArray.fromObject(getContext().getCoreLibrary().getArrayClass(), object);
} else {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertTo(
getContext().getCoreLibrary().getLogicalClass(object).getName(),
"Array",
method,
getContext().getCoreLibrary().getLogicalClass(array).getName(),
this)
object, getContext().getCoreLibrary().getArrayClass(), method, array, this)
);
}
}
31 changes: 12 additions & 19 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.cast.BooleanCastNode;
import org.jruby.truffle.nodes.cast.BooleanCastNodeFactory;
import org.jruby.truffle.nodes.cast.NumericToFloatNode;
import org.jruby.truffle.nodes.cast.NumericToFloatNodeFactory;
import org.jruby.truffle.nodes.control.WhileNode;
import org.jruby.truffle.nodes.core.KernelNodesFactory.SameOrEqualNodeFactory;
import org.jruby.truffle.nodes.dispatch.*;
@@ -1924,7 +1926,7 @@ public Object string(VirtualFrame frame, Object value) {
@CoreMethod(names = "sleep", isModuleFunction = true, optional = 1)
public abstract static class SleepNode extends CoreMethodNode {

@Child CallDispatchHeadNode floatNode;
@Child NumericToFloatNode floatCastNode;

public SleepNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
@@ -1940,11 +1942,6 @@ public long sleep(UndefinedPlaceholder duration) {
return doSleepMillis(Long.MAX_VALUE);
}

@Specialization(guards = "isRubiniusUndefined")
public long sleep(RubyBasicObject duration) {
return sleep(UndefinedPlaceholder.INSTANCE);
}

@Specialization
public long sleep(int duration) {
return doSleepMillis(duration * 1000);
@@ -1960,22 +1957,18 @@ public long sleep(double duration) {
return doSleepMillis((long) (duration * 1000));
}

@Specialization(guards = "isRational")
@Specialization(guards = "isRubiniusUndefined")
public long sleep(RubyBasicObject duration) {
return sleep(UndefinedPlaceholder.INSTANCE);
}

@Specialization(guards = "!isRubiniusUndefined")
public long sleep(VirtualFrame frame, RubyBasicObject duration) {
if (floatNode == null) {
if (floatCastNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
floatNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
floatCastNode = insert(NumericToFloatNodeFactory.create(getContext(), getSourceSection(), "to_f", null));
}

try {
return sleep(floatNode.callFloat(frame, duration, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(duration).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
}

return sleep(floatCastNode.executeFloat(frame, duration));
}

@TruffleBoundary
48 changes: 12 additions & 36 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/MathNodes.java
Original file line number Diff line number Diff line change
@@ -424,17 +424,13 @@ public RubyArray frexp(VirtualFrame frame, Object a) {
return frexp(floatNode.callFloat(frame, a, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

@@ -610,17 +606,13 @@ public double function(VirtualFrame frame, Object a, Object b) {
integerBNode.callLongFixnum(frame, b, "to_int", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getIntegerClass().getName(),
this));
a, getContext().getCoreLibrary().getIntegerClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

@@ -682,17 +674,13 @@ public RubyArray lgamma(VirtualFrame frame, Object a) {
return lgamma(floatNode.callFloat(frame, a, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

@@ -737,17 +725,13 @@ public double function(VirtualFrame frame, Object a, UndefinedPlaceholder b) {
floatANode.callFloat(frame, a, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

@@ -960,17 +944,13 @@ public double function(VirtualFrame frame, Object a) {
return doFunction(floatNode.callFloat(frame, a, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

@@ -1091,17 +1071,13 @@ public double function(VirtualFrame frame, Object a, Object b) {
floatBNode.callFloat(frame, b, "to_f", null));
} catch (UseMethodMissingException e) {
throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
} else {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().typeErrorCantConvertInto(
getContext().getCoreLibrary().getLogicalClass(a).getName(),
getContext().getCoreLibrary().getFloatClass().getName(),
this));
a, getContext().getCoreLibrary().getFloatClass(), this));
}
}

Original file line number Diff line number Diff line change
@@ -72,17 +72,8 @@ public double callFloat(
}

CompilerDirectives.transferToInterpreter();

final String message = String.format("%s (%s#%s gives %s)",
context.getCoreLibrary().getFloatClass().getName(),
context.getCoreLibrary().getLogicalClass(receiverObject).getName(),
methodName,
context.getCoreLibrary().getLogicalClass(value).getName());

throw new RaiseException(context.getCoreLibrary().typeErrorCantConvertTo(
context.getCoreLibrary().getLogicalClass(receiverObject).getName(),
message,
this));
receiverObject, context.getCoreLibrary().getFloatClass(), (String) methodName, value, this));
}

public long callLongFixnum(
@@ -106,17 +97,8 @@ public long callLongFixnum(
}

CompilerDirectives.transferToInterpreter();

final String message = String.format("%s (%s#%s gives %s)",
context.getCoreLibrary().getFloatClass().getName(),
context.getCoreLibrary().getLogicalClass(receiverObject).getName(),
methodName,
context.getCoreLibrary().getLogicalClass(value).getName());

throw new RaiseException(context.getCoreLibrary().typeErrorCantConvertTo(
context.getCoreLibrary().getLogicalClass(receiverObject).getName(),
message,
this));
receiverObject, context.getCoreLibrary().getFixnumClass(), (String) methodName, value, this));
}

}
Original file line number Diff line number Diff line change
@@ -627,24 +627,16 @@ public RubyException typeErrorShouldReturn(String object, String method, String
return typeError(String.format("%s#%s should return %s", object, method, expectedType), currentNode);
}

public RubyException typeErrorCantConvertTo(String from, String to, Node currentNode) {
public RubyException typeErrorCantConvertTo(Object from, RubyClass to, String methodUsed, Object result, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return typeError(String.format("can't convert %s to %s", from, to), currentNode);
}

public RubyException typeErrorCantConvertTo(String from, String to, String methodUsed, String given, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return typeError(String.format("can't convert %s to %s (%s#%s gives %s)", from, to, from, methodUsed, given), currentNode);
}

public RubyException typeErrorCantConvertInto(String from, String to, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return typeError(String.format("can't convert %s into %s", from, to), currentNode);
String fromClass = getLogicalClass(from).getName();
return typeError(String.format("can't convert %s to %s (%s#%s gives %s)",
fromClass, to.getName(), fromClass, methodUsed, getLogicalClass(result).toString()), currentNode);
}

public RubyException typeErrorCantConvertInto(Object from, RubyClass to, Node currentNode) {
CompilerAsserts.neverPartOfCompilation();
return typeErrorCantConvertInto(getLogicalClass(from).getName(), to.getName(), currentNode);
return typeError(String.format("can't convert %s into %s", getLogicalClass(from).getName(), to.getName()), currentNode);
}

public RubyException typeErrorIsNotA(String value, String expectedType, Node currentNode) {
Original file line number Diff line number Diff line change
@@ -97,10 +97,10 @@ public void run() {
context.getSafepointManager().leaveThread();
finalThread.manager.unregisterThread(finalThread);

finalThread.finished.countDown();
status = Status.DEAD;
thread = null;
releaseOwnedLocks();
finalThread.finished.countDown();
}
}