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

Commits on Jun 26, 2017

  1. Copy the full SHA
    b069a8a View commit details
  2. Coverage changes for 2.4. #4293

    headius committed Jun 26, 2017
    Copy the full SHA
    26a4ba7 View commit details
  3. Copy the full SHA
    b58ed3e View commit details
  4. Copy the full SHA
    efba830 View commit details
  5. Copy the full SHA
    4f06d7b View commit details
  6. Copy the full SHA
    f92ae0d View commit details
  7. [2.4] Partially implement NameError#private_call? #4293

    This is a partial impl since we do not have the actual original
    call type available when the exception is created.
    headius committed Jun 26, 2017
    Copy the full SHA
    f124c49 View commit details
  8. Copy the full SHA
    266df24 View commit details
  9. Copy the full SHA
    2c170b3 View commit details
36 changes: 31 additions & 5 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -3863,6 +3863,13 @@ public RaiseException newIllegalSequence(String message) {
return newRaiseException(getClass("Iconv").getClass("IllegalSequence"), message);
}

/**
* @see Ruby#newNameError(String, IRubyObject, IRubyObject, boolean)
*/
public RaiseException newNameError(String message, IRubyObject recv, IRubyObject name) {
return newNameError(message, recv, name, false);
}

/**
* Construct a NameError that formats its message with an sprintf format string.
*
@@ -3880,11 +3887,12 @@ public RaiseException newIllegalSequence(String message) {
* @param message an sprintf format string for the message
* @param recv the receiver object
* @param name the name that failed
* @param privateCall whether the failure was due to method visibility
* @return a new NameError
*/
public RaiseException newNameError(String message, IRubyObject recv, IRubyObject name) {
public RaiseException newNameError(String message, IRubyObject recv, IRubyObject name, boolean privateCall) {
IRubyObject msg = new RubyNameError.RubyNameErrorMessage(this, message, recv, name);
RubyException err = RubyNameError.newNameError(getNameError(), msg, name);
RubyException err = RubyNameError.newNameError(getNameError(), msg, name, privateCall);

return new RaiseException(err);
}
@@ -3897,8 +3905,19 @@ public RaiseException newNameError(String message, IRubyObject recv, IRubyObject
* @see Ruby#newNameError(String, IRubyObject, IRubyObject)
*/
public RaiseException newNameError(String message, IRubyObject recv, String name) {
return newNameError(message, recv, name, false);
}

/**
* Construct a NameError that formats its message with an sprintf format string and has private_call? set to given.
*
* This version just accepts a java.lang.String for the name.
*
* @see Ruby#newNameError(String, IRubyObject, IRubyObject)
*/
public RaiseException newNameError(String message, IRubyObject recv, String name, boolean privateCall) {
RubySymbol nameSym = newSymbol(name);
return newNameError(message, recv, nameSym);
return newNameError(message, recv, nameSym, privateCall);
}

/**
@@ -3954,6 +3973,13 @@ public RaiseException newNameError(String message, String name, Throwable origEx
return newNameError(message, name, origException, false);
}

/**
* @see Ruby#newNoMethodError(String, IRubyObject, String, RubyArray, boolean)
*/
public RaiseException newNoMethodError(String message, IRubyObject recv, String name, RubyArray args) {
return newNoMethodError(message, recv, name, args, false);
}

/**
* Construct a NoMethodError that formats its message with an sprintf format string.
*
@@ -3964,10 +3990,10 @@ public RaiseException newNameError(String message, String name, Throwable origEx
*
* @return a new NoMethodError
*/
public RaiseException newNoMethodError(String message, IRubyObject recv, String name, RubyArray args) {
public RaiseException newNoMethodError(String message, IRubyObject recv, String name, RubyArray args, boolean privateCall) {
RubySymbol nameStr = newSymbol(name);
IRubyObject msg = new RubyNameError.RubyNameErrorMessage(this, message, recv, nameStr);
RubyException err = RubyNoMethodError.newNoMethodError(getNoMethodError(), msg, nameStr, args);
RubyException err = RubyNoMethodError.newNoMethodError(getNoMethodError(), msg, nameStr, args, privateCall);

return new RaiseException(err);
}
4 changes: 3 additions & 1 deletion core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
@@ -2012,8 +2012,10 @@ public static IRubyObject chunk(ThreadContext context, IRubyObject self, final I

@JRubyMethod
public static IRubyObject chunk(ThreadContext context, IRubyObject self, final Block block) {
final Ruby runtime = context.runtime;

if(!block.isGiven()) {
return enumeratorize(context.runtime, self, "chunk");
return enumeratorizeWithSize(context, self, "chunk", enumSizeFn(context, self));
}

IRubyObject enumerator = context.runtime.getEnumerator().allocate();
6 changes: 5 additions & 1 deletion core/src/main/java/org/jruby/RubyGlobal.java
Original file line number Diff line number Diff line change
@@ -394,7 +394,7 @@ public CaseInsensitiveStringOnlyRubyHash(Ruby runtime, Map<RubyString, RubyStrin

@Override
public IRubyObject op_aref(ThreadContext context, IRubyObject key) {
return case_aware_op_aref(context, key, false);
return asTainted(case_aware_op_aref(context, key, false));
}

@Override
@@ -417,6 +417,10 @@ public RubyHash to_h(){
return to_hash();
}

private IRubyObject asTainted(IRubyObject obj) {
obj.setTaint(true);
return obj;
}

}

6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
@@ -211,6 +211,12 @@ public static final RubyHash newSmallHash(Ruby runtime) {
return new RubyHash(runtime, 1);
}

public static RubyHash newKwargs(Ruby runtime, String key, IRubyObject value) {
RubyHash kwargs = newSmallHash(runtime);
kwargs.fastASetSmall(runtime.newSymbol(key), value);
return kwargs;
}

/** rb_hash_new
*
*/
11 changes: 9 additions & 2 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -237,10 +237,17 @@ public static IRubyObject methodMissing(ThreadContext context, IRubyObject recv,
public static IRubyObject methodMissing(ThreadContext context, IRubyObject recv, String name, Visibility lastVis, CallType lastCallType, IRubyObject[] args, boolean dropFirst) {
Ruby runtime = context.runtime;

boolean privateCall = false;
if (lastCallType == CallType.VARIABLE || lastCallType == CallType.FUNCTIONAL) {
privateCall = true;
} else if (lastVis == PUBLIC) {
privateCall = true;
}

if (lastCallType != CallType.VARIABLE) {
throw runtime.newNoMethodError(getMethodMissingFormat(lastVis, lastCallType), recv, name, RubyArray.newArrayMayCopy(runtime, args, dropFirst ? 1 : 0));
throw runtime.newNoMethodError(getMethodMissingFormat(lastVis, lastCallType), recv, name, RubyArray.newArrayMayCopy(runtime, args, dropFirst ? 1 : 0), privateCall);
} else {
throw runtime.newNameError(getMethodMissingFormat(lastVis, lastCallType), recv, name);
throw runtime.newNameError(getMethodMissingFormat(lastVis, lastCallType), recv, name, privateCall);
}
}

18 changes: 15 additions & 3 deletions core/src/main/java/org/jruby/RubyNameError.java
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@
public class RubyNameError extends RubyException {
private IRubyObject name;
private IRubyObject receiver;
protected boolean privateCall;

/**
* Nested class whose instances act as thunks reacting to to_str method
@@ -194,7 +195,7 @@ public static RubyException exception(ThreadContext context, IRubyObject recv, I

@JRubyMethod(name = "exception", meta = true)
public static RubyException exception(ThreadContext context, IRubyObject recv, IRubyObject message, IRubyObject name) {
return newNameError(recv, message, name);
return newNameError(recv, message, name, false);
}

private static RubyException newNameError(IRubyObject recv, IRubyObject[] args) {
@@ -206,12 +207,14 @@ private static RubyException newNameError(IRubyObject recv, IRubyObject[] args)
return newError;
}

static RubyException newNameError(IRubyObject recv, IRubyObject message, IRubyObject name) {
static RubyException newNameError(IRubyObject recv, IRubyObject message, IRubyObject name, boolean privateCall) {
final RubyClass klass = (RubyClass) recv;
RubyException newError = (RubyException) klass.allocate();
RubyNameError newError = (RubyNameError) klass.allocate();

newError.callInit(message, name, Block.NULL_BLOCK);

newError.privateCall = privateCall;

return newError;
}

@@ -251,10 +254,19 @@ public IRubyObject receiver(ThreadContext context) {
throw context.runtime.newArgumentError("no receiver is available");
}

@JRubyMethod(name = "private_call?")
public IRubyObject private_call_p(ThreadContext context) {
return context.runtime.newBoolean(isPrivateCall());
}

@Override
public void copySpecialInstanceVariables(IRubyObject clone) {
super.copySpecialInstanceVariables(clone);
RubyNameError exception = (RubyNameError)clone;
exception.name = name;
}

public boolean isPrivateCall() {
return privateCall;
}
}
12 changes: 12 additions & 0 deletions core/src/main/java/org/jruby/RubyNoMethodError.java
Original file line number Diff line number Diff line change
@@ -72,6 +72,18 @@ public static RubyException newNoMethodError(IRubyObject recv, IRubyObject messa
return newError;
}

public static RubyException newNoMethodError(IRubyObject recv, IRubyObject message, IRubyObject name, IRubyObject args, boolean privateCall) {
RubyClass klass = (RubyClass)recv;

RubyNoMethodError newError = (RubyNoMethodError) klass.allocate();

newError.callInit(message, name, args, Block.NULL_BLOCK);

newError.privateCall = privateCall;

return newError;
}

@JRubyMethod(rest = true, visibility = Visibility.PRIVATE)
@Override
public IRubyObject initialize(IRubyObject[] args, Block block) {
62 changes: 46 additions & 16 deletions core/src/main/java/org/jruby/RubyRational.java
Original file line number Diff line number Diff line change
@@ -233,13 +233,10 @@ static IRubyObject intValue(ThreadContext context, IRubyObject num) {
*
*/
private static IRubyObject canonicalizeInternal(ThreadContext context, IRubyObject clazz, IRubyObject num, IRubyObject den) {
Ruby runtime = context.runtime;
IRubyObject res = f_cmp(context, den, RubyFixnum.zero(runtime));
if (res == RubyFixnum.minus_one(runtime)) {
// MRI: nurat_canonicalize, negation part
if (canonicalizeShouldNegate(context, num, den)) {
num = f_negate(context, num);
den = f_negate(context, den);
} else if (res == RubyFixnum.zero(runtime)) {
throw runtime.newZeroDivisionError();
}

IRubyObject gcd = f_gcd(context, num, den);
@@ -257,13 +254,10 @@ private static IRubyObject canonicalizeInternal(ThreadContext context, IRubyObje
*
*/
private static IRubyObject canonicalizeInternalNoReduce(ThreadContext context, IRubyObject clazz, IRubyObject num, IRubyObject den) {
Ruby runtime = context.runtime;
IRubyObject res = f_cmp(context, den, RubyFixnum.zero(runtime));
if (res == RubyFixnum.minus_one(runtime)) {
// MRI: nurat_canonicalize, negation part
if (canonicalizeShouldNegate(context, num, den)) {
num = f_negate(context, num);
den = f_negate(context, den);
} else if (res == RubyFixnum.zero(runtime)) {
throw runtime.newZeroDivisionError();
}

if (Numeric.CANON && canonicalization && f_one_p(context, den)) {
@@ -272,6 +266,18 @@ private static IRubyObject canonicalizeInternalNoReduce(ThreadContext context, I

return new RubyRational(context.runtime, clazz, num, den);
}

// MRI: nurat_canonicalize, value check part
private static boolean canonicalizeShouldNegate(ThreadContext context, IRubyObject num, IRubyObject den) {
Ruby runtime = context.runtime;
IRubyObject res = f_cmp(context, den, RubyFixnum.zero(runtime));
if (res == RubyFixnum.minus_one(runtime)) {
return true;
} else if (res == RubyFixnum.zero(runtime)) {
throw runtime.newZeroDivisionError();
}
return false;
}

/** nurat_s_new
*
@@ -1013,12 +1019,21 @@ public IRubyObject marshal_dump(ThreadContext context) {
@JRubyMethod(name = "marshal_load")
public IRubyObject marshal_load(ThreadContext context, IRubyObject arg) {
RubyArray load = arg.convertToArray();
num = load.size() > 0 ? load.eltInternal(0) : context.runtime.getNil();
den = load.size() > 1 ? load.eltInternal(1) : context.runtime.getNil();
IRubyObject num = load.size() > 0 ? load.eltInternal(0) : context.nil;
IRubyObject den = load.size() > 1 ? load.eltInternal(1) : context.nil;

intCheck(context, num);
intCheck(context, den);

if (f_zero_p(context, den)) {
throw context.runtime.newZeroDivisionError();
// MRI: nurat_canonicalize, negation part
if (canonicalizeShouldNegate(context, num, den)) {
num = f_negate(context, num);
den = f_negate(context, den);
}

this.num = num;
this.den = den;

if (load.hasVariables()) syncVariables((IRubyObject)load);
return this;
}
@@ -1033,9 +1048,24 @@ public void marshalTo(Ruby runtime, Object obj, RubyClass type,
@Override
public Object unmarshalFrom(Ruby runtime, RubyClass type,
UnmarshalStream unmarshalStream) throws IOException {
ThreadContext context = runtime.getCurrentContext();

RubyRational r = (RubyRational) RubyClass.DEFAULT_OBJECT_MARSHAL.unmarshalFrom(runtime, type, unmarshalStream);
r.num = r.removeInstanceVariable("@numerator");
r.den = r.removeInstanceVariable("@denominator");
IRubyObject num = r.removeInstanceVariable("@numerator");
IRubyObject den = r.removeInstanceVariable("@denominator");

intCheck(context, num);
intCheck(context, den);

// MRI: nurat_canonicalize, negation part
if (canonicalizeShouldNegate(context, num, den)) {
num = f_negate(context, num);
den = f_negate(context, den);
}

r.num = num;
r.den = den;

return r;
}
};
38 changes: 23 additions & 15 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -258,7 +258,7 @@ private void executeInterrupts(ThreadContext context, boolean blockingTiming) {
if (status.get() == Status.SLEEP) {
exitSleep();
}
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[]{err}, Block.NULL_BLOCK);
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[]{err, RubyHash.newKwargs(runtime, "cause", ((RubyException) err).cause)}, Block.NULL_BLOCK);
}
}

@@ -1288,42 +1288,50 @@ public IRubyObject genericRaise(Ruby runtime, IRubyObject[] args, RubyThread cur

private IRubyObject prepareRaiseException(Ruby runtime, IRubyObject[] args, Block block) {
if (args.length == 0) {
IRubyObject lastException = errorInfo;
if (lastException.isNil()) {
if (errorInfo.isNil()) {
return new RaiseException(runtime, runtime.getRuntimeError(), "", false).getException();
}
return lastException;
return errorInfo;
}

final ThreadContext context = runtime.getCurrentContext();
final IRubyObject arg = args[0];

final IRubyObject exception;
IRubyObject tmp;
final RubyException exception;
if (args.length == 1) {
if (arg instanceof RubyString) {
return runtime.getRuntimeError().newInstance(context, args, block);
tmp = runtime.getRuntimeError().newInstance(context, args, block);
}
if (arg instanceof ConcreteJavaProxy ) {
else if (arg instanceof ConcreteJavaProxy ) {
return arg;
}
if ( ! arg.respondsTo("exception") ) {
return runtime.newTypeError("exception class/object expected").getException();
else if ( ! arg.respondsTo("exception") ) {
throw runtime.newTypeError("exception class/object expected");
} else {
tmp = arg.callMethod(context, "exception");
}
exception = arg.callMethod(context, "exception");
} else {
if ( ! arg.respondsTo("exception") ) {
return runtime.newTypeError("exception class/object expected").getException();
throw runtime.newTypeError("exception class/object expected");
}

exception = arg.callMethod(context, "exception", args[1]);
tmp = arg.callMethod(context, "exception", args[1]);
}

if (!runtime.getException().isInstance(exception)) {
return runtime.newTypeError("exception object expected").getException();
if (!runtime.getException().isInstance(tmp)) {
throw runtime.newTypeError("exception object expected");
}

exception = (RubyException) tmp;

if (args.length == 3) {
((RubyException) exception).set_backtrace(args[2]);
exception.set_backtrace(args[2]);
}

IRubyObject cause = context.getErrorInfo();
if (cause != exception) {
exception.setCause(cause);
}

return exception;
Loading