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

Commits on Feb 22, 2016

  1. Copy the full SHA
    0774fe4 View commit details
  2. Typo in exclude.

    headius committed Feb 22, 2016
    Copy the full SHA
    a5fd8ef View commit details
  3. Copy the full SHA
    e704b9e View commit details
  4. Rehome "fiber current thread" and access directly for locals.

    Fixes MRI TestThread#test_thread_variable?.
    headius committed Feb 22, 2016
    Copy the full SHA
    f191aba View commit details
  5. Fix Math to invoke to_f when appropriate and rewrite num2dbl.

    New behaviors match MRI 2.3 and fix MRI
    TestMath#test_override_bignum_to_f.
    headius committed Feb 22, 2016
    Copy the full SHA
    9044aec View commit details
  6. Tweaks to MRI Math tests to improve reliability.

    * to_f override tests need to ensure they put old to_f back.
    * Test of Bignum#to_f override needs to ensure it's a Bignum.
    headius committed Feb 22, 2016
    Copy the full SHA
    88881b7 View commit details
68 changes: 28 additions & 40 deletions core/src/main/java/org/jruby/RubyMath.java
Original file line number Diff line number Diff line change
@@ -87,27 +87,15 @@ public static double sign(double x, double y) {
double abs = ((x < 0) ? -x : x);
return (y < 0.0) ? -abs : abs;
}

private static RubyFloat needFloat(IRubyObject x) {
if (x instanceof RubyFloat) {
return (RubyFloat)x;
}

if (!x.getRuntime().getNumeric().isInstance(x)) {
TypeConverter.handleUncoercibleObject(true, x, x.getRuntime().getFloat());
}

return (RubyFloat) TypeConverter.convertToType19(x, x.getRuntime().getFloat(), "to_f", true);
}

public static RubyFloat atan2(ThreadContext context, IRubyObject recv, IRubyObject x, IRubyObject y) {
return atan219(context, recv, x, y);
}

@JRubyMethod(name = "atan2", required = 2, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat atan219(ThreadContext context, IRubyObject recv, IRubyObject x, IRubyObject y) {
double valuea = needFloat(x).getDoubleValue();
double valueb = needFloat(y).getDoubleValue();
double valuea = RubyNumeric.num2dbl(x);
double valueb = RubyNumeric.num2dbl(y);

return RubyFloat.newFloat(context.runtime, Math.atan2(valuea, valueb));
}
@@ -118,7 +106,7 @@ public static RubyFloat cos(ThreadContext context, IRubyObject recv, IRubyObject

@JRubyMethod(name = "cos", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat cos19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return RubyFloat.newFloat(context.runtime, Math.cos(needFloat(x).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.cos(RubyNumeric.num2dbl(x)));
}

public static RubyFloat sin(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -127,7 +115,7 @@ public static RubyFloat sin(ThreadContext context, IRubyObject recv, IRubyObject

@JRubyMethod(name = "sin", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat sin19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return RubyFloat.newFloat(context.runtime, Math.sin(needFloat(x).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.sin(RubyNumeric.num2dbl(x)));
}

public static RubyFloat tan(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -136,7 +124,7 @@ public static RubyFloat tan(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "tan", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat tan19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return RubyFloat.newFloat(context.runtime, Math.tan(needFloat(x).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.tan(RubyNumeric.num2dbl(x)));
}

public static RubyFloat asin(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -145,7 +133,7 @@ public static RubyFloat asin(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "asin", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat asin19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

if (value < -1.0 || value > 1.0) throw context.runtime.newMathDomainError("asin");

@@ -158,7 +146,7 @@ public static RubyFloat acos(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "acos", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat acos19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

if (value < -1.0 || value > 1.0) throw context.runtime.newMathDomainError("acos");

@@ -171,7 +159,7 @@ public static RubyFloat atan(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "atan", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat atan19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return RubyFloat.newFloat(context.runtime, Math.atan(needFloat(x).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.atan(RubyNumeric.num2dbl(x)));
}

public static RubyFloat cosh(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -180,7 +168,7 @@ public static RubyFloat cosh(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "cosh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat cosh19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

return RubyFloat.newFloat(context.runtime, (Math.exp(value) + Math.exp(-value)) / 2.0);
}
@@ -191,7 +179,7 @@ public static RubyFloat sinh(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "sinh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat sinh19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

return RubyFloat.newFloat(context.runtime, (Math.exp(value) - Math.exp(-value)) / 2.0);
}
@@ -202,7 +190,7 @@ public static RubyFloat tanh(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "tanh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat tanh19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return RubyFloat.newFloat(context.runtime, Math.tanh(needFloat(x).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.tanh(RubyNumeric.num2dbl(x)));
}

public static RubyFloat acosh(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -211,7 +199,7 @@ public static RubyFloat acosh(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "acosh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat acosh19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);
double result;

if (Double.isNaN(value)) {
@@ -257,7 +245,7 @@ public static RubyFloat asinh(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "asinh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat asinh19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);
double y = Math.abs(value);
double result;

@@ -302,7 +290,7 @@ public static RubyFloat atanh(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "atanh", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat atanh_19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

if (value < -1.0 || value > 1.0) throw context.runtime.newMathDomainError("atanh");

@@ -338,7 +326,7 @@ public static RubyFloat exp(ThreadContext context, IRubyObject recv, IRubyObject

@JRubyMethod(name = "exp", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat exp19(ThreadContext context, IRubyObject recv, IRubyObject exponent) {
return RubyFloat.newFloat(context.runtime, Math.exp(needFloat(exponent).getDoubleValue()));
return RubyFloat.newFloat(context.runtime, Math.exp(RubyNumeric.num2dbl(exponent)));
}

private static RubyFloat log_common19(IRubyObject recv, double value, double base, String msg) {
@@ -352,10 +340,10 @@ private static RubyFloat log_common19(IRubyObject recv, double value, double bas
*/
@JRubyMethod(name = "log", required = 1, optional = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat log_19(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
double value = needFloat(args[0]).getDoubleValue();
double value = RubyNumeric.num2dbl(args[0]);
double base = Math.E;
if (args.length == 2) {
base = needFloat(args[1]).getDoubleValue();
base = RubyNumeric.num2dbl(args[1]);
}
return log_common19(recv, value, base, "log");
}
@@ -369,7 +357,7 @@ public static RubyFloat log10(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "log10", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat log10_19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return log_common19(recv, needFloat(x).getDoubleValue(), 10, "log10");
return log_common19(recv, RubyNumeric.num2dbl(x), 10, "log10");
}

/** Returns the base 2 logarithm of x.
@@ -381,7 +369,7 @@ public static RubyFloat log2(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "log2", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat log2_19(ThreadContext context, IRubyObject recv, IRubyObject x) {
return log_common19(recv, needFloat(x).getDoubleValue(), 2, "log2");
return log_common19(recv, RubyNumeric.num2dbl(x), 2, "log2");
}

public static RubyFloat sqrt(ThreadContext context, IRubyObject recv, IRubyObject x) {
@@ -390,7 +378,7 @@ public static RubyFloat sqrt(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "sqrt", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat sqrt19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);
double result;

if (value < 0) {
@@ -406,7 +394,7 @@ public static RubyFloat sqrt19(ThreadContext context, IRubyObject recv, IRubyObj

@JRubyMethod(name = "cbrt", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat cbrt(ThreadContext context, IRubyObject recv, IRubyObject x) {
double result = Math.cbrt(needFloat(x).getDoubleValue());
double result = Math.cbrt(RubyNumeric.num2dbl(x));

domainCheck(recv, result, "cbrt");

@@ -419,8 +407,8 @@ public static RubyFloat hypot(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "hypot", required = 2, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat hypot19(ThreadContext context, IRubyObject recv, IRubyObject x, IRubyObject y) {
double valuea = needFloat(x).getDoubleValue();
double valueb = needFloat(y).getDoubleValue();
double valuea = RubyNumeric.num2dbl(x);
double valueb = RubyNumeric.num2dbl(y);
double result;

if (Math.abs(valuea) > Math.abs(valueb)) {
@@ -451,7 +439,7 @@ public static RubyArray frexp(ThreadContext context, IRubyObject recv, IRubyObje

@JRubyMethod(name = "frexp", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyArray frexp19(ThreadContext context, IRubyObject recv, IRubyObject other) {
double mantissa = needFloat(other).getDoubleValue();
double mantissa = RubyNumeric.num2dbl(other);
short sign = 1;
long exponent = 0;

@@ -484,7 +472,7 @@ public static RubyFloat ldexp(ThreadContext context, IRubyObject recv, IRubyObje
@JRubyMethod(name = "ldexp", required = 2, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat ldexp19(ThreadContext context, IRubyObject recv, IRubyObject mantissa, IRubyObject exponent) {
return RubyFloat.newFloat(context.runtime,
needFloat(mantissa).getDoubleValue() * Math.pow(2.0, RubyNumeric.num2int(exponent)));
RubyNumeric.num2dbl(mantissa) * Math.pow(2.0, RubyNumeric.num2int(exponent)));
}

public static final double[] ERFC_COEF = {
@@ -510,7 +498,7 @@ public static RubyFloat erf(IRubyObject recv, IRubyObject x) {

@JRubyMethod(name = "erf", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat erf19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);

double result;
double y = Math.abs(value);
@@ -598,7 +586,7 @@ public static RubyFloat erfc(ThreadContext context, IRubyObject recv, IRubyObjec

@JRubyMethod(name = "erfc", required = 1, module = true, visibility = Visibility.PRIVATE)
public static RubyFloat erfc19(ThreadContext context, IRubyObject recv, IRubyObject x) {
double value = needFloat(x).getDoubleValue();
double value = RubyNumeric.num2dbl(x);
double result;
double y = Math.abs(value);

@@ -720,7 +708,7 @@ public static RubyFloat gamma(ThreadContext context, IRubyObject recv, IRubyObje
* @param x a real number
* @return 2-element array [ln(&Gamma;(x)), sgn] for real number x,
* where sgn is the sign of &Gamma;(x) when exponentiated
* @see #gamma(org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject)
* @see #gamma(ThreadContext, org.jruby.runtime.builtin.IRubyObject, org.jruby.runtime.builtin.IRubyObject)
*/

@JRubyMethod(name = "lgamma", required = 1, module = true, visibility = Visibility.PRIVATE)
23 changes: 18 additions & 5 deletions core/src/main/java/org/jruby/RubyNumeric.java
Original file line number Diff line number Diff line change
@@ -61,6 +61,7 @@
import static org.jruby.util.Numeric.f_arg;
import static org.jruby.util.Numeric.f_mul;
import static org.jruby.util.Numeric.f_negative_p;
import static org.jruby.util.Numeric.f_to_f;

/**
* Base class for all numerical types in ruby.
@@ -248,14 +249,26 @@ public static IRubyObject dbl2num(Ruby runtime, double val) {
*
*/
public static double num2dbl(IRubyObject arg) {
Ruby runtime = arg.getRuntime();

if (arg instanceof RubyBoolean || arg instanceof RubyNil) {
throw runtime.newTypeError("can't convert " + arg.inspect() + " into Float");
}

if (arg instanceof RubyFloat) {
return ((RubyFloat) arg).getDoubleValue();
} else if (arg instanceof RubyString) {
throw arg.getRuntime().newTypeError("no implicit conversion to float from string");
} else if (arg == arg.getRuntime().getNil()) {
throw arg.getRuntime().newTypeError("no implicit conversion to float from nil");
} else if (arg instanceof RubyBignum) {
if (runtime.getBignum().searchMethod("to_f").isBuiltin()) {
return ((RubyBignum) arg).getDoubleValue();
}
} else if (arg instanceof RubyRational) {
if (runtime.getRational().searchMethod("to_f").isBuiltin()) {
return ((RubyRational) arg).getDoubleValue();
}
}
return RubyKernel.new_float(arg, arg).getDoubleValue();

IRubyObject val = f_to_f(runtime.getCurrentContext(), arg);
return ((RubyFloat) val).getDoubleValue();
}

/** rb_dbl_cmp (numeric.c)
25 changes: 17 additions & 8 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -195,6 +195,8 @@ public static enum Status {

private volatile Selector currentSelector;

private volatile RubyThread fiberCurrentThread;

private static final AtomicIntegerFieldUpdater<RubyThread> INTERRUPT_FLAG_UPDATER =
AtomicIntegerFieldUpdater.newUpdater(RubyThread.class, "interruptFlag");

@@ -360,11 +362,19 @@ public ThreadContext getContext() {
return contextRef == null ? null : contextRef.get();
}


public Thread getNativeThread() {
return threadImpl.nativeThread();
}

public void setFiberCurrentThread(RubyThread fiberCurrentThread) {
this.fiberCurrentThread = fiberCurrentThread;
}

public RubyThread getFiberCurrentThread() {
if (fiberCurrentThread == null) return this;
return fiberCurrentThread;
}

/**
* Perform pre-execution tasks once the native thread is running, but we
* have not yet called the Ruby code for the thread.
@@ -875,8 +885,8 @@ private synchronized Map<IRubyObject, IRubyObject> getFiberLocals() {
return fiberLocalVariables;
}

private synchronized Map<IRubyObject, IRubyObject> getThreadLocals(ThreadContext context) {
return context.getFiberCurrentThread().getThreadLocals0();
private synchronized Map<IRubyObject, IRubyObject> getThreadLocals() {
return getFiberCurrentThread().getThreadLocals0();
}

private synchronized Map<IRubyObject, IRubyObject> getThreadLocals0() {
@@ -916,14 +926,13 @@ public synchronized IRubyObject op_aset(IRubyObject key, IRubyObject value) {

@JRubyMethod(name = "thread_variable?", required = 1)
public synchronized IRubyObject thread_variable_p(ThreadContext context, IRubyObject key) {
IRubyObject value;
return context.runtime.newBoolean(getThreadLocals(context).containsKey(getSymbolKey(key)));
return context.runtime.newBoolean(getThreadLocals().containsKey(getSymbolKey(key)));
}

@JRubyMethod(name = "thread_variable_get", required = 1)
public synchronized IRubyObject thread_variable_get(ThreadContext context, IRubyObject key) {
IRubyObject value;
if ((value = getThreadLocals(context).get(getSymbolKey(key))) != null) {
if ((value = getThreadLocals().get(getSymbolKey(key))) != null) {
return value;
}
return context.runtime.getNil();
@@ -935,14 +944,14 @@ public synchronized IRubyObject thread_variable_set(ThreadContext context, IRuby

key = getSymbolKey(key);

getThreadLocals(context).put(key, value);
getThreadLocals().put(key, value);

return value;
}

@JRubyMethod(name = "thread_variables")
public synchronized IRubyObject thread_variables(ThreadContext context) {
Map<IRubyObject, IRubyObject> vars = getThreadLocals(context);
Map<IRubyObject, IRubyObject> vars = getThreadLocals();
RubyArray ary = RubyArray.newArray(context.runtime, vars.size());
for (Map.Entry<IRubyObject, IRubyObject> entry : vars.entrySet()) {
ary.append(entry.getKey());
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ext/fiber/ThreadFiber.java
Original file line number Diff line number Diff line change
@@ -242,8 +242,8 @@ static RubyThread createThread(final Ruby runtime, final FiberData data, final F
public void run() {
ThreadContext context = runtime.getCurrentContext();
context.setFiber(data.fiber.get());
context.setRootThread(data.parent);
fiberThread.set(context.getThread());
context.getThread().setFiberCurrentThread(data.parent);

try {
IRubyObject init = data.queue.pop(context);
Loading