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: aa684402c426
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4218b04a90bc
Choose a head ref
  • 7 commits
  • 21 files changed
  • 2 contributors

Commits on Jul 17, 2017

  1. Copy the full SHA
    03ba517 View commit details
  2. Copy the full SHA
    fab4883 View commit details
  3. Copy the full SHA
    0058cf0 View commit details
  4. Copy the full SHA
    5e8fc15 View commit details
  5. Pushed through Symbols to IR local variables. Also encode/decode

    AOT/persistence to store symbols instead of Java strings...possibly first time
    we can AOT non-Java supported encodings as local variables?
    enebo committed Jul 17, 2017
    Copy the full SHA
    59903c0 View commit details
  6. identifier is dead. removing...

    enebo committed Jul 17, 2017
    Copy the full SHA
    fe35f48 View commit details
  7. Copy the full SHA
    4218b04 View commit details
18 changes: 14 additions & 4 deletions core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
@@ -947,6 +947,9 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
});
}

if (result[0] instanceof RubyFloat) {
return ((RubyFloat) result[0]).op_plus(context, memo[0]);
}
return result[0];
}

@@ -955,7 +958,11 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
public static IRubyObject sumAdd(final ThreadContext ctx, IRubyObject lhs, IRubyObject rhs, final double c[]) {
boolean floats = false;
double f = 0.0;
double x = 0.0, y, t;
/*
* Kahan-Babuska balancing compensated summation algorithm
* See http://link.springer.com/article/10.1007/s00607-005-0139-x
*/
double x = 0.0, t;
if (lhs instanceof RubyFloat) {
if (rhs instanceof RubyFloat) {
f = ((RubyFloat) lhs).getValue();
@@ -998,9 +1005,12 @@ public static IRubyObject sumAdd(final ThreadContext ctx, IRubyObject lhs, IRuby
}

// Kahan's compensated summation algorithm
y = x - c[0];
t = f + y;
c[0] = (t - f) - y;
t = f + x;
if (Math.abs(f) >= Math.abs(x)) {
c[0] += ((f - t) + x);
} else {
c[0] += ((x - t) + f);
}
f = t;

return new RubyFloat(ctx.runtime, f);
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ast/DAsgnNode.java
Original file line number Diff line number Diff line change
@@ -35,15 +35,15 @@

import org.jruby.Ruby;
import org.jruby.RubySymbol;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.types.ISymbolNameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.util.ByteList;

/**
* An assignment to a dynamic variable (e.g. block scope local variable).
*/
public class DAsgnNode extends AssignableNode implements INameNode, IScopedNode {
public class DAsgnNode extends AssignableNode implements ISymbolNameNode, IScopedNode {
// The name of the variable
private RubySymbol name;

4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ast/LocalAsgnNode.java
Original file line number Diff line number Diff line change
@@ -36,15 +36,15 @@

import org.jruby.Ruby;
import org.jruby.RubySymbol;
import org.jruby.ast.types.INameNode;
import org.jruby.ast.types.ISymbolNameNode;
import org.jruby.ast.visitor.NodeVisitor;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.util.ByteList;

/**
* An assignment to a local variable.
*/
public class LocalAsgnNode extends AssignableNode implements INameNode, IScopedNode {
public class LocalAsgnNode extends AssignableNode implements ISymbolNameNode, IScopedNode {
// The name of the variable
private RubySymbol name;

115 changes: 75 additions & 40 deletions core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyConstant;
import org.jruby.anno.JRubyMethod;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.JavaSites;
@@ -95,7 +96,7 @@ public RubyBigDecimal allocate(Ruby runtime, RubyClass klass) {
@JRubyConstant
public final static int SIGN_POSITIVE_INFINITE = 3;
@JRubyConstant
public final static int EXCEPTION_OVERFLOW = 8;
public final static int EXCEPTION_OVERFLOW = 1; // Note: This is same as EXCEPTION_INFINITY in MRI now
@JRubyConstant
public final static int SIGN_POSITIVE_ZERO = 1;
@JRubyConstant
@@ -305,10 +306,11 @@ private static IRubyObject modeExecute(final ThreadContext context, final RubyMo

@JRubyMethod(required = 1, optional = 1, meta = true)
public static IRubyObject mode(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
Ruby runtime = context.runtime;

// FIXME: I doubt any of the constants referenced in this method
// are ever redefined -- should compare to the known values, rather
// than do an expensive constant lookup.
RubyClass clazz = context.runtime.getClass("BigDecimal");
RubyModule c = (RubyModule)recv;

args = Arity.scanArgs(context.runtime, args, 1, 1);
@@ -321,53 +323,48 @@ public static IRubyObject mode(ThreadContext context, IRubyObject recv, IRubyObj
}

long longMode = ((RubyFixnum)mode).getLongValue();
long _EXCEPTION_ALL = bigDecimalConst(context.runtime, "EXCEPTION_ALL");
if ((longMode & _EXCEPTION_ALL) != 0) {
if ((longMode & EXCEPTION_ALL) != 0) {
if (value.isNil()) return c.searchInternalModuleVariable("vpExceptionMode");
if (!(value instanceof RubyBoolean)) throw context.runtime.newArgumentError("second argument must be true or false");

RubyFixnum currentExceptionMode = (RubyFixnum)c.searchInternalModuleVariable("vpExceptionMode");
RubyFixnum newExceptionMode = new RubyFixnum(context.runtime, currentExceptionMode.getLongValue());
long newExceptionMode = c.searchInternalModuleVariable("vpExceptionMode").convertToInteger().getLongValue();

boolean enable = value.isTrue();

RubyFixnum _EXCEPTION_INFINITY = (RubyFixnum)clazz.getConstant("EXCEPTION_INFINITY");
if ((longMode & _EXCEPTION_INFINITY.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_INFINITY)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_INFINITY).getLongValue()));
if ((longMode & EXCEPTION_INFINITY) != 0) {
newExceptionMode = enable ? newExceptionMode | EXCEPTION_INFINITY : newExceptionMode & ~(EXCEPTION_INFINITY);
}

RubyFixnum _EXCEPTION_NaN = (RubyFixnum)clazz.getConstant("EXCEPTION_NaN");
if ((longMode & _EXCEPTION_NaN.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_NaN)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_NaN).getLongValue()));
if ((longMode & EXCEPTION_NaN) != 0) {
newExceptionMode = enable ? newExceptionMode | EXCEPTION_NaN : newExceptionMode & ~(EXCEPTION_NaN);
}

RubyFixnum _EXCEPTION_UNDERFLOW = (RubyFixnum)clazz.getConstant("EXCEPTION_UNDERFLOW");
if ((longMode & _EXCEPTION_UNDERFLOW.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_UNDERFLOW)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_UNDERFLOW).getLongValue()));
if ((longMode & EXCEPTION_UNDERFLOW) != 0) {
newExceptionMode = enable ? newExceptionMode | EXCEPTION_UNDERFLOW : newExceptionMode & ~(EXCEPTION_UNDERFLOW);
}
RubyFixnum _EXCEPTION_OVERFLOW = (RubyFixnum)clazz.getConstant("EXCEPTION_OVERFLOW");
if ((longMode & _EXCEPTION_OVERFLOW.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_OVERFLOW)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_OVERFLOW).getLongValue()));

if ((longMode & EXCEPTION_ZERODIVIDE) != 0) {
newExceptionMode = enable ? newExceptionMode | EXCEPTION_ZERODIVIDE : newExceptionMode & ~(EXCEPTION_ZERODIVIDE);
}
c.setInternalModuleVariable("vpExceptionMode", newExceptionMode);
return newExceptionMode;

RubyFixnum fixnumMode = RubyFixnum.newFixnum(runtime, newExceptionMode);
c.setInternalModuleVariable("vpExceptionMode", fixnumMode);
return fixnumMode;
}

long ROUND_MODE = ((RubyFixnum)clazz.getConstant("ROUND_MODE")).getLongValue();
if (longMode == ROUND_MODE) {
if (value.isNil()) {
return c.searchInternalModuleVariable("vpRoundingMode");
}

RoundingMode javaRoundingMode = javaRoundingModeFromRubyRoundingMode(context.runtime, value);
RubyFixnum roundingMode = context.runtime.newFixnum(javaRoundingMode.ordinal());
RoundingMode javaRoundingMode = javaRoundingModeFromRubyRoundingMode(runtime, value);
RubyFixnum roundingMode = runtime.newFixnum(javaRoundingMode.ordinal());
c.setInternalModuleVariable("vpRoundingMode", roundingMode);

return c.searchInternalModuleVariable("vpRoundingMode");
}
throw context.runtime.newTypeError("first argument for BigDecimal#mode invalid");

throw runtime.newTypeError("first argument for BigDecimal#mode invalid");
}

private static RubyModule bigDecimal(Ruby runtime) {
@@ -389,15 +386,15 @@ private static RoundingMode getRoundingMode(Ruby runtime) {
}

private static boolean isNaNExceptionMode(Ruby runtime) {
return (bigDecimalVar(runtime, "vpExceptionMode") & bigDecimalConst(runtime, "EXCEPTION_NaN")) != 0;
return (bigDecimalVar(runtime, "vpExceptionMode") & EXCEPTION_NaN) != 0;
}

private static boolean isInfinityExceptionMode(Ruby runtime) {
return (bigDecimalVar(runtime, "vpExceptionMode") & bigDecimalConst(runtime, "EXCEPTION_INFINITY")) != 0;
return (bigDecimalVar(runtime, "vpExceptionMode") & EXCEPTION_INFINITY) != 0;
}

private static boolean isOverflowExceptionMode(Ruby runtime) {
return (bigDecimalVar(runtime, "vpExceptionMode") & bigDecimalConst(runtime, "EXCEPTION_OVERFLOW")) != 0;
return (bigDecimalVar(runtime, "vpExceptionMode") & EXCEPTION_OVERFLOW) != 0;
}

private static RubyBigDecimal cannotBeCoerced(ThreadContext context, IRubyObject value, boolean must) {
@@ -1354,6 +1351,8 @@ public IRubyObject precs(ThreadContext context) {

@JRubyMethod(name = "round", optional = 2)
public IRubyObject round(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.runtime;

// Special treatment for BigDecimal::NAN and BigDecimal::INFINITY
//
// If round is called without any argument, we should raise a
@@ -1363,16 +1362,30 @@ public IRubyObject round(ThreadContext context, IRubyObject[] args) {
StringBuilder message = new StringBuilder("Computation results to ");
message.append('\'').append(callMethod(context, "to_s")).append('\'');

throw context.runtime.newFloatDomainError(message.toString());
throw runtime.newFloatDomainError(message.toString());
} else {
if (isNaN()) return newNaN(context.runtime);
if (isNaN()) return newNaN(runtime);
if (isInfinity()) {
return newInfinity(context.runtime, infinitySign);
return newInfinity(runtime, infinitySign);
}
}

final int scale = args.length > 0 ? num2int(args[0]) : 0;
RoundingMode mode = (args.length > 1) ? javaRoundingModeFromRubyRoundingMode(context.runtime, args[1]) : getRoundingMode(context.runtime);
RoundingMode mode = getRoundingMode(runtime);
int scale = 0;

int argc = args.length;
switch (argc) {
case 2:
mode = javaRoundingModeFromRubyRoundingMode(runtime, args[1]);
scale = num2int(args[0]);
case 1:
if (ArgsUtil.getOptionsArg(runtime, args[0]).isNil()) {
scale = num2int(args[0]);
} else {
mode = javaRoundingModeFromRubyRoundingMode(runtime, args[0]);
}
}

// JRUBY-914: Java 1.4 BigDecimal does not allow a negative scale, so we have to simulate it
final RubyBigDecimal bigDecimal;
if (scale < 0) {
@@ -1382,9 +1395,9 @@ public IRubyObject round(ThreadContext context, IRubyObject[] args) {
// ...round to that digit
BigDecimal rounded = normalized.setScale(0, mode);
// ...and shift the result back to the left (multiply by 10**(abs(scale)))
bigDecimal = new RubyBigDecimal(context.runtime, rounded.movePointLeft(scale));
bigDecimal = new RubyBigDecimal(runtime, rounded.movePointLeft(scale));
} else {
bigDecimal = new RubyBigDecimal(context.runtime, value.setScale(scale, mode));
bigDecimal = new RubyBigDecimal(runtime, value.setScale(scale, mode));
}

return args.length == 0 ? bigDecimal.to_int() : bigDecimal;
@@ -1396,8 +1409,29 @@ public IRubyObject round(ThreadContext context, IRubyObject scale, IRubyObject m

//this relies on the Ruby rounding enumerations == Java ones, which they (currently) all are
private static RoundingMode javaRoundingModeFromRubyRoundingMode(Ruby runtime, IRubyObject arg) {
IRubyObject opts = ArgsUtil.getOptionsArg(runtime, arg);
if (!opts.isNil()) {
arg = ArgsUtil.extractKeywordArg(runtime.getCurrentContext(), "half", opts);
if (arg.isNil()) {
return getRoundingMode(runtime);
}
String roundingMode = arg.asJavaString();
switch (roundingMode) {
case "up":
return RoundingMode.HALF_UP;
case "down" :
return RoundingMode.HALF_DOWN;
case "even" :
return RoundingMode.HALF_EVEN;
default :
throw runtime.newArgumentError("invalid rounding mode: " + roundingMode);
}
}
if (arg.isNil()) {
return getRoundingMode(runtime);
}
if (arg instanceof RubySymbol) {
String roundingMode = ((RubySymbol) arg).asJavaString();
String roundingMode = arg.asJavaString();
switch (roundingMode) {
case "up" :
return RoundingMode.UP;
@@ -1410,6 +1444,7 @@ private static RoundingMode javaRoundingModeFromRubyRoundingMode(Ruby runtime, I
case "half_down" :
return RoundingMode.HALF_DOWN;
case "half_even" :
case "even" :
case "banker" :
return RoundingMode.HALF_EVEN;
case "ceiling" :
@@ -1418,7 +1453,7 @@ private static RoundingMode javaRoundingModeFromRubyRoundingMode(Ruby runtime, I
case "floor" :
return RoundingMode.FLOOR;
default :
throw runtime.newArgumentError("invalid rounding mode");
throw runtime.newArgumentError("invalid rounding mode: " + roundingMode);
}
} else {
try {
Loading