Skip to content

Commit

Permalink
Merge branch 'master' into truffle-antlr-printf
Browse files Browse the repository at this point in the history
# Conflicts:
#	truffle/src/main/java/org/jruby/truffle/format/parser/FormatParser.java
#	truffle/src/main/java/org/jruby/truffle/format/parser/FormatTokenizer.java
chrisseaton committed Dec 19, 2015
2 parents f9d23da + 2e8c47d commit fd56628
Showing 132 changed files with 1,254 additions and 798 deletions.
26 changes: 20 additions & 6 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -1612,7 +1612,9 @@ private void initExceptions() {
typeError = defineClassIfAllowed("TypeError", standardError);
argumentError = defineClassIfAllowed("ArgumentError", standardError);
indexError = defineClassIfAllowed("IndexError", standardError);
stopIteration = defineClassIfAllowed("StopIteration", indexError);
if (profile.allowClass("StopIteration")) {
stopIteration = RubyStopIteration.createStopIterationClass(this, indexError);
}
syntaxError = defineClassIfAllowed("SyntaxError", scriptError);
loadError = defineClassIfAllowed("LoadError", scriptError);
notImplementedError = defineClassIfAllowed("NotImplementedError", scriptError);
@@ -4073,7 +4075,7 @@ private RaiseException newLightweightErrnoException(RubyClass exceptionClass, St
if (RubyInstanceConfig.ERRNO_BACKTRACE) {
return new RaiseException(this, exceptionClass, message, true);
} else {
return new RaiseException(this, exceptionClass, ERRNO_BACKTRACE_MESSAGE, RubyArray.newEmptyArray(this), true);
return new RaiseException(this, exceptionClass, ERRNO_BACKTRACE_MESSAGE, disabledBacktrace(), true);
}
}

@@ -4088,12 +4090,24 @@ private RaiseException newLightweightErrnoException(RubyClass exceptionClass, St
*
* @param message the message for the exception
*/
public RaiseException newLightweightStopIterationError(String message) {
public RaiseException newStopIteration(IRubyObject result, String message) {
final ThreadContext context = getCurrentContext();
if (RubyInstanceConfig.STOPITERATION_BACKTRACE) {
return new RaiseException(this, stopIteration, message, true);
} else {
return new RaiseException(this, stopIteration, STOPIERATION_BACKTRACE_MESSAGE, RubyArray.newEmptyArray(this), true);
RubyException ex = RubyStopIteration.newInstance(context, result, message);
return new RaiseException(ex);
}
if ( message == null ) message = STOPIERATION_BACKTRACE_MESSAGE;
RubyException ex = RubyStopIteration.newInstance(context, result, message);
return new RaiseException(ex, disabledBacktrace());
}

@Deprecated
public RaiseException newLightweightStopIterationError(String message) {
return newStopIteration(null, message);
}

private IRubyObject disabledBacktrace() {
return RubyArray.newEmptyArray(this);
}

// Equivalent of Data_Wrap_Struct
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -2321,7 +2321,7 @@ public RubyArray collectBang(ThreadContext context, Block block) {
*/
@JRubyMethod(name = "collect!")
public IRubyObject collect_bang(ThreadContext context, Block block) {
return block.isGiven() ? collectBang(context, block) : enumeratorize(context.runtime, this, "collect!");
return block.isGiven() ? collectBang(context, block) : enumeratorizeWithSize(context, this, "collect!", enumLengthFn());
}

/** rb_ary_collect_bang
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
@@ -1138,6 +1138,9 @@ public static void checkInheritable(IRubyObject superClass) {
if (((RubyClass)superClass).isSingleton()) {
throw superClass.getRuntime().newTypeError("can't make subclass of virtual class");
}
if (superClass == superClass.getRuntime().getClassClass()) {
throw superClass.getRuntime().newTypeError("can't make subclass of Class");
}
}

public final ObjectMarshal getMarshal() {
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
@@ -1201,6 +1201,7 @@ public static IRubyObject max_by(ThreadContext context, IRubyObject self, final

@JRubyMethod
public static IRubyObject max_by(ThreadContext context, IRubyObject self, IRubyObject arg, final Block block) {
if (arg == context.nil) return singleExtentBy(context, self, "max", SORT_MAX, block);
// TODO: Replace with an implementation (quickselect, etc) which requires O(k) memory rather than O(n) memory
RubyArray sorted = (RubyArray)sort_by(context, self, block);
return ((RubyArray) sorted.last(arg)).reverse();
@@ -1213,6 +1214,7 @@ public static IRubyObject min_by(ThreadContext context, IRubyObject self, final

@JRubyMethod
public static IRubyObject min_by(ThreadContext context, IRubyObject self, IRubyObject arg, final Block block) {
if (arg == context.nil) return singleExtentBy(context, self, "min", SORT_MIN, block);
// TODO: Replace with an implementation (quickselect, etc) which requires O(k) memory rather than O(n) memory
RubyArray sorted = (RubyArray)sort_by(context, self, block);
return sorted.first(arg);
112 changes: 57 additions & 55 deletions core/src/main/java/org/jruby/RubyEnumerator.java
Original file line number Diff line number Diff line change
@@ -95,22 +95,22 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
private RubyEnumerator(Ruby runtime, RubyClass type) {
super(runtime, type);
object = runtime.getNil();
initialize(runtime.getNil(), RubyString.newEmptyString(runtime), IRubyObject.NULL_ARRAY);
initialize(runtime, runtime.getNil(), RubyString.newEmptyString(runtime), IRubyObject.NULL_ARRAY);
}

private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[]args, IRubyObject size) {
private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[] args, IRubyObject size) {
super(runtime, type);
initialize20(object, method, args, size, null);
initialize20(runtime, object, method, args, size, null);
}

private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[]args, SizeFn sizeFn) {
private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[] args, SizeFn sizeFn) {
super(runtime, type);
initialize20(object, method, args, null, sizeFn);
initialize20(runtime, object, method, args, null, sizeFn);
}

private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[]args) {
private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[] args) {
super(runtime, type);
initialize(object, method, args);
initialize(runtime, object, method, args);
}

/**
@@ -186,13 +186,13 @@ public IRubyObject initialize20(ThreadContext context, IRubyObject[] args, Block
size = args[0];
args = Arrays.copyOfRange(args, 1, args.length);

if (!(size.isNil() || size.respondsTo("call")) &&
!(runtime.getFloat().isInstance(size) && ((RubyFloat)size).getDoubleValue() == Float.POSITIVE_INFINITY) &&
!(size instanceof RubyInteger)) {
if ( ! (size.isNil() || size.respondsTo("call")) &&
! (runtime.getFloat().isInstance(size) && ((RubyFloat) size).getDoubleValue() == Float.POSITIVE_INFINITY) &&
! (size instanceof RubyInteger) ) {
throw runtime.newTypeError(size, runtime.getInteger());
}
}
object = context.runtime.getGenerator().newInstance(context, IRubyObject.NULL_ARRAY, block);
object = runtime.getGenerator().newInstance(context, IRubyObject.NULL_ARRAY, block);

} else {
Arity.checkArgumentCount(runtime, args, 1, -1);
@@ -205,7 +205,7 @@ public IRubyObject initialize20(ThreadContext context, IRubyObject[] args, Block
}
}

return initialize20(object, method, args, size, null);
return initialize20(runtime, object, method, args, size, null);
}

public IRubyObject initialize(ThreadContext context, IRubyObject object, IRubyObject method) {
@@ -220,9 +220,8 @@ public IRubyObject initialize19(ThreadContext context, IRubyObject object, IRuby
public IRubyObject initialize20(ThreadContext context, IRubyObject object, IRubyObject method, Block block) {
if (block.isGiven()) {
throw context.runtime.newArgumentError(2, 1);
} else {
return initialize(object, method, NULL_ARRAY);
}
return initialize(context.runtime, object, method, NULL_ARRAY);
}

public IRubyObject initialize(ThreadContext context, IRubyObject object, IRubyObject method, IRubyObject methodArg) {
@@ -237,9 +236,8 @@ public IRubyObject initialize19(ThreadContext context, IRubyObject object, IRuby
public IRubyObject initialize20(ThreadContext context, IRubyObject object, IRubyObject method, IRubyObject methodArg, Block block) {
if (block.isGiven()) {
throw context.runtime.newArgumentError(3, 1);
} else {
return initialize(object, method, new IRubyObject[] { methodArg });
}
return initialize(context.runtime, object, method, new IRubyObject[] { methodArg });
}

public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
@@ -250,12 +248,11 @@ public IRubyObject initialize19(ThreadContext context, IRubyObject[] args, Block
return initialize20(context, args, block);
}

private IRubyObject initialize(IRubyObject object, IRubyObject method, IRubyObject[] methodArgs) {
return initialize20(object, method, methodArgs, null, null);
private IRubyObject initialize(Ruby runtime, IRubyObject object, IRubyObject method, IRubyObject[] methodArgs) {
return initialize20(runtime, object, method, methodArgs, null, null);
}

private IRubyObject initialize20(IRubyObject object, IRubyObject method, IRubyObject[] methodArgs, IRubyObject size, SizeFn sizeFn) {
final Ruby runtime = getRuntime();
private IRubyObject initialize20(Ruby runtime, IRubyObject object, IRubyObject method, IRubyObject[] methodArgs, IRubyObject size, SizeFn sizeFn) {
this.object = object;
this.method = method.asJavaString();
this.methodArgs = methodArgs;
@@ -438,7 +435,7 @@ private IRubyObject with_index_common(ThreadContext context, final Block block,

@JRubyMethod
public IRubyObject each_with_index(ThreadContext context, final Block block) {
return with_index_common(context, block, "each_with_index", context.runtime.getNil());
return with_index_common(context, block, "each_with_index", context.nil);
}

public IRubyObject with_index(ThreadContext context, final Block block) {
@@ -447,7 +444,7 @@ public IRubyObject with_index(ThreadContext context, final Block block) {

@JRubyMethod(name = "with_index")
public IRubyObject with_index19(ThreadContext context, final Block block) {
return with_index_common(context, block, "with_index", context.runtime.getNil());
return with_index_common(context, block, "with_index", context.nil);
}

@JRubyMethod(name = "with_index")
@@ -615,15 +612,15 @@ protected IRubyObject get() {
}

private void checkIndex() throws RaiseException {
if (index >= array.size()) throw runtime.newLightweightStopIterationError("stop iteration");
if (index >= array.size()) throw runtime.newStopIteration(array, null);
}
}

private static class ThreadedNexter extends Nexter implements Runnable {
private static final boolean DEBUG = false;

/** sync queue to wait for values */
private SynchronousQueue<IRubyObject> out = new SynchronousQueue<IRubyObject>();
final SynchronousQueue<IRubyObject> out = new SynchronousQueue<IRubyObject>();

/** thread that's executing this Nexter */
private volatile Thread thread;
@@ -640,6 +637,9 @@ private static class ThreadedNexter extends Nexter implements Runnable {
/** the last value we got, used for peek */
private IRubyObject lastValue;

/** the block return value, to be fed as StopIteration#result */
private volatile IRubyObject stopValue;

/** Exception used for unrolling the iteration on terminate */
private static class TerminateEnumeration extends RuntimeException implements Unrescuable {}

@@ -729,7 +729,7 @@ private IRubyObject returnValue(IRubyObject value) {
// if it's the NEVER object, raise StopIteration
if (value == NEVER) {
doneObject = value;
throw runtime.newLightweightStopIterationError("stop iteration");
throw runtime.newStopIteration(stopValue, "iteration reached an end");
}

// if it's an exception, raise it
@@ -754,38 +754,41 @@ public void run() {
IRubyObject finalObject = NEVER;

try {
IRubyObject oldExc = runtime.getGlobalVariables().get("$!"); // Save $!
final IRubyObject oldExc = runtime.getGlobalVariables().get("$!"); // Save $!
final TerminateEnumeration terminateEnumeration = new TerminateEnumeration();
try {
object.callMethod(context, method, methodArgs, CallBlock.newCallClosure(object, object.getMetaClass(), Signature.OPTIONAL, new BlockCallback() {
@Override
public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
try {
if (DEBUG) System.out.println(Thread.currentThread().getName() + ": exchanging: " + Arrays.toString(args));
if (die) throw terminateEnumeration;
out.put(RubyEnumerable.packEnumValues(context, args));
if (die) throw terminateEnumeration;
} catch (InterruptedException ie) {
if (DEBUG) System.out.println(Thread.currentThread().getName() + ": interrupted");

throw terminateEnumeration;
}

IRubyObject feedValue = getFeedValue();
setFeedValue(context.nil);
return feedValue;
Block generatorClosure = CallBlock.newCallClosure(object, object.getMetaClass(), Signature.OPTIONAL, new BlockCallback() {

public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
try {
if (DEBUG) System.out.println(Thread.currentThread().getName() + ": exchanging: " + Arrays.toString(args));
if (die) throw terminateEnumeration;
out.put( RubyEnumerable.packEnumValues(context, args) );
if (die) throw terminateEnumeration;
}
}, context));
} catch (TerminateEnumeration te) {
if (te != terminateEnumeration) {
throw te;
catch (InterruptedException ie) {
if (DEBUG) System.out.println(Thread.currentThread().getName() + ": interrupted");

throw terminateEnumeration;
}

IRubyObject feedValue = getFeedValue();
setFeedValue(context.nil);
return feedValue;
}
}, context);
try {
this.stopValue = object.callMethod(context, method, methodArgs, generatorClosure);
}
catch (TerminateEnumeration te) {
if (te != terminateEnumeration) throw te;
// ignore, we're shutting down
} catch (RaiseException re) {
}
catch (RaiseException re) {
if (DEBUG) System.out.println(Thread.currentThread().getName() + ": exception at toplevel: " + re.getException());
finalObject = re.getException();
runtime.getGlobalVariables().set("$!", oldExc); // Restore $!
} catch (Throwable t) {
}
catch (Throwable t) {
if (DEBUG) {
System.out.println(Thread.currentThread().getName() + ": exception at toplevel: " + t);
t.printStackTrace();
@@ -795,12 +798,11 @@ public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block)

try {
if (!die) out.put(finalObject);
} catch (InterruptedException ie) {
// ignore
}
} finally {
// disassociate this Nexter with the thread running it
thread = null;
catch (InterruptedException ie) { /* ignore */ }
}
finally {
thread = null; // disassociate this Nexter with the thread running it
}
}
}
Loading

0 comments on commit fd56628

Please sign in to comment.