Skip to content
Browse files

Merge branch 'master' into fast

  • Loading branch information...
2 parents ad3d2f0 + 852a031 commit 3e92a39a8e5ee3b2e3580075c993a5341cfe1a90 @headius headius committed
View
2 .classpath
@@ -29,7 +29,7 @@
<classpathentry kind="lib" path="build_lib/asm-commons-3.2.jar"/>
<classpathentry kind="lib" path="build_lib/asm-util-3.2.jar"/>
<classpathentry kind="lib" path="build_lib/jnr-posix.jar"/>
- <classpathentry kind="lib" path="build_lib/joda-time-1.6.jar"/>
+ <classpathentry kind="lib" path="build_lib/joda-time-1.6.1.jar"/>
<classpathentry kind="lib" path="build_lib/jgrapht-jdk1.5.jar"/>
<classpathentry kind="lib" path="build_lib/livetribe-jsr223-2.0.6.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANT"/>
View
7 lib/ruby/site_ruby/shared/syslog.rb
@@ -107,15 +107,16 @@ def open(ident=nil, opt=nil, fac=nil)
self
end
- alias_method :open!, :open
##
# like open, but closes it first
- def reopen(*args)
+ def reopen(*args, &block)
close
- open(*args)
+ open(*args, &block)
end
+ alias_method :open!, :reopen
+
##
# Is it open?
def opened?
View
1 spec/tags/1.8/ruby/core/string/sub_tags.txt
@@ -1 +0,0 @@
-fails:String#sub! with pattern and block raises a RuntimeError when self is frozen
View
1 spec/tags/1.8/ruby/library/socket/ipsocket/addr_tags.txt
@@ -1 +0,0 @@
-fails(JRUBY-2791,macos):Socket::IPSocket#addr returns an array with the socket's information
View
1 spec/tags/1.8/ruby/library/socket/ipsocket/peeraddr_tags.txt
@@ -1 +0,0 @@
-fails(JRUBY-2791,macos):Socket::IPSocket#peeraddr returns an array of information on the peer
View
1 spec/tags/1.8/ruby/library/socket/tcpsocket/gethostbyname_tags.txt
@@ -1 +0,0 @@
-fails(JRUBY-2791,macos):TCPSocket#gethostbyname returns the canonical name as first value
View
12 spec/tags/1.9/ruby/core/string/modulo_tags.txt
@@ -1,12 +0,0 @@
-fails:String#% supports binary formats using %b for negative numbers
-fails:String#% supports negative integers using %d, giving priority to `-`
-fails:String#% supports negative integers using %i, giving priority to `-`
-fails:String#% supports octal formats using %o for negative numbers
-fails:String#% supports negative bignums with %u or %d
-fails:String#% supports hex formats using %x for negative numbers
-fails:String#% supports hex formats using %X for negative numbers
-fails:String#% behaves as if calling Kernel#Float for %e arguments, when the passed argument is hexadecimal string
-fails:String#% behaves as if calling Kernel#Float for %E arguments, when the passed argument is hexadecimal string
-fails:String#% behaves as if calling Kernel#Float for %f arguments, when the passed argument is hexadecimal string
-fails:String#% behaves as if calling Kernel#Float for %g arguments, when the passed argument is hexadecimal string
-fails:String#% behaves as if calling Kernel#Float for %G arguments, when the passed argument is hexadecimal string
View
26 src/org/jruby/Ruby.java
@@ -3208,7 +3208,9 @@ public RaiseException newIllegalSequence(String message) {
}
public RaiseException newNoMethodError(String message, String name, IRubyObject args) {
- return new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args), true);
+ RaiseException exception = new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args), true);
+ exception.preRaise(getCurrentContext());
+ return exception;
}
public RaiseException newNameError(String message, String name) {
@@ -3223,12 +3225,18 @@ public RaiseException newNameError(String message, String name, Throwable origEx
if (printWhenVerbose && origException != null && this.isVerbose()) {
origException.printStackTrace(getErrorStream());
}
- return new RaiseException(new RubyNameError(
+
+ RaiseException exception = new RaiseException(new RubyNameError(
this, getNameError(), message, name), false);
+ exception.preRaise(getCurrentContext());
+
+ return exception;
}
public RaiseException newLocalJumpError(RubyLocalJumpError.Reason reason, IRubyObject exitValue, String message) {
- return new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), message, reason, exitValue), true);
+ RaiseException exception = new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), message, reason, exitValue), true);
+ exception.preRaise(getCurrentContext());
+ return exception;
}
public RaiseException newLocalJumpErrorNoBlock() {
@@ -3236,7 +3244,7 @@ public RaiseException newLocalJumpErrorNoBlock() {
}
public RaiseException newRedoLocalJumpError() {
- return new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), "unexpected redo", RubyLocalJumpError.Reason.REDO, getNil()), true);
+ return newLocalJumpError(RubyLocalJumpError.Reason.REDO, getNil(), "unexpected redo");
}
public RaiseException newLoadError(String message) {
@@ -3244,8 +3252,12 @@ public RaiseException newLoadError(String message) {
}
public RaiseException newFrozenError(String objectType) {
+ return newFrozenError(objectType, false);
+ }
+
+ public RaiseException newFrozenError(String objectType, boolean runtimeError) {
// TODO: Should frozen error have its own distinct class? If not should more share?
- return newRaiseException(is1_9() ? getRuntimeError() : getTypeError(), "can't modify frozen " + objectType);
+ return newRaiseException(is1_9() || runtimeError ? getRuntimeError() : getTypeError(), "can't modify frozen " + objectType);
}
public RaiseException newSystemStackError(String message) {
@@ -3260,7 +3272,9 @@ public RaiseException newSystemStackError(String message, StackOverflowError soe
}
public RaiseException newSystemExit(int status) {
- return new RaiseException(RubySystemExit.newInstance(this, status));
+ RaiseException exception = new RaiseException(RubySystemExit.newInstance(this, status));
+ exception.preRaise(getCurrentContext());
+ return exception;
}
public RaiseException newIOError(String message) {
View
31 src/org/jruby/RubyKernel.java
@@ -71,6 +71,7 @@
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.IAutoloadMethod;
import org.jruby.runtime.load.LoadService;
+import org.jruby.util.ConvertBytes;
import org.jruby.util.IdUtil;
import org.jruby.util.ShellLauncher;
import org.jruby.util.TypeConverter;
@@ -267,7 +268,9 @@ private static IRubyObject methodMissing(ThreadContext context, IRubyObject recv
exArgs = new IRubyObject[]{msg, symbol};
}
- throw new RaiseException((RubyException)exc.newInstance(context, exArgs, Block.NULL_BLOCK));
+ RaiseException exception = new RaiseException((RubyException)exc.newInstance(context, exArgs, Block.NULL_BLOCK));
+ exception.preRaise(context);
+ throw exception;
}
@JRubyMethod(name = "open", required = 1, optional = 2, frame = true, module = true, visibility = PRIVATE)
@@ -363,22 +366,26 @@ public static RubyFloat new_float(IRubyObject recv, IRubyObject object) {
@JRubyMethod(name = "Float", module = true, visibility = PRIVATE, compat = CompatVersion.RUBY1_9)
public static RubyFloat new_float19(IRubyObject recv, IRubyObject object) {
+ Ruby runtime = recv.getRuntime();
if(object instanceof RubyFixnum){
- return RubyFloat.newFloat(object.getRuntime(), ((RubyFixnum)object).getDoubleValue());
- }else if(object instanceof RubyFloat){
+ return RubyFloat.newFloat(runtime, ((RubyFixnum)object).getDoubleValue());
+ } else if (object instanceof RubyFloat) {
return (RubyFloat)object;
- }else if(object instanceof RubyBignum){
- return RubyFloat.newFloat(object.getRuntime(), RubyBignum.big2dbl((RubyBignum)object));
- }else if(object instanceof RubyString){
+ } else if(object instanceof RubyBignum){
+ return RubyFloat.newFloat(runtime, RubyBignum.big2dbl((RubyBignum)object));
+ } else if(object instanceof RubyString){
if(((RubyString) object).getByteList().getRealSize() == 0){ // rb_cstr_to_dbl case
- throw recv.getRuntime().newArgumentError("invalid value for Float(): " + object.inspect());
+ throw runtime.newArgumentError("invalid value for Float(): " + object.inspect());
}
- return RubyNumeric.str2fnum(recv.getRuntime(),(RubyString)object,true);
- }else if(object.isNil()){
- throw recv.getRuntime().newTypeError("can't convert nil into Float");
+ RubyString arg = (RubyString)object;
+ if (arg.toString().startsWith("0x")) {
+ return ConvertBytes.byteListToInum19(runtime, arg.getByteList(), 16, true).toFloat();
+ }
+ return RubyNumeric.str2fnum19(runtime, arg,true);
+ } else if(object.isNil()){
+ throw runtime.newTypeError("can't convert nil into Float");
} else {
- RubyFloat rFloat = (RubyFloat)TypeConverter.convertToType19(object, recv.getRuntime().getFloat(), "to_f");
- return rFloat;
+ return (RubyFloat)TypeConverter.convertToType19(object, runtime.getFloat(), "to_f");
}
}
View
10 src/org/jruby/RubyString.java
@@ -705,7 +705,11 @@ private final void modifyCheck(byte[] b, int len, Encoding enc) {
}
private void frozenCheck() {
- if (isFrozen()) throw getRuntime().newFrozenError("string");
+ frozenCheck(false);
+ }
+
+ private void frozenCheck(boolean runtimeError) {
+ if (isFrozen()) throw getRuntime().newFrozenError("string", runtimeError);
}
/** rb_str_modify
@@ -2391,14 +2395,14 @@ private IRubyObject subBangIter(ThreadContext context, Regex pattern, Block bloc
DynamicScope scope = context.getCurrentScope();
if (matcher.search(value.getBegin(), range, Option.NONE) >= 0) {
- frozenCheck();
+ frozenCheck(true);
byte[] bytes = value.getUnsafeBytes();
int size = value.getRealSize();
RubyMatchData match = RubyRegexp.updateBackRef(context, this, scope, matcher, pattern);
RubyString repl = objAsString(context, block.yield(context,
makeShared(context.getRuntime(), matcher.getBegin(), matcher.getEnd() - matcher.getBegin())));
modifyCheck(bytes, size);
- frozenCheck();
+ frozenCheck(true);
scope.setBackRef(match);
return subBangCommon(context, pattern, matcher, repl, repl.flags);
} else {
View
8 src/org/jruby/compiler/ir/IR_Builder.java
@@ -1719,10 +1719,14 @@ public Operand buildEnsureNode(Node node, IR_Scope m) {
// ensure
// .. something else ..
// end
+ //
if (ebi.noFallThru)
m.addInstr(new LABEL_Instr(ebi.start));
+ // Pop the current ensure block info node *BEFORE* generating the ensure code for this block itself!
+ _ensureBlockStack.pop();
+
// Two cases:
// 1. Ensure block has no explicit return => the result of the entire ensure expression is the result of the protected body.
// 2. Ensure block has an explicit return => the result of the protected body is ignored.
@@ -1736,8 +1740,6 @@ public Operand buildEnsureNode(Node node, IR_Scope m) {
m.addInstr(new LABEL_Instr(ebi.end));
}
- _ensureBlockStack.pop();
-
return rv;
}
@@ -2690,7 +2692,7 @@ public Operand buildRetry(Node node, IR_Scope s) {
public Operand buildReturn(ReturnNode returnNode, IR_Scope m) {
Operand retVal = (returnNode.getValueNode() == null) ? Nil.NIL : build(returnNode.getValueNode(), m);
- // Before we return, have to go execute all the ensure blocks
+ // Before we return, have to go execute all the ensure blocks (except the one we are currently executing!)
if (!_ensureBlockStack.empty())
EnsureBlockInfo.emitJumpChain(m, _ensureBlockStack);
m.addInstr(new RETURN_Instr(retVal));
View
11 src/org/jruby/compiler/ir/dataflow/analyses/LiveVariableNode.java
@@ -223,6 +223,17 @@ void markDeadInstructions()
{
// System.out.println("dead processing for " + _bb.getID());
LiveVariablesProblem lvp = (LiveVariablesProblem)_prob;
+
+ if (_out == null) {
+ // _out cannot be null for reachable bbs!
+ // This bb is unreachable! (or we have a mighty bug!)
+ // Mark everything dead in here!
+ for (IR_Instr i: _bb.getInstrs())
+ i.markDead();
+
+ return;
+ }
+
_tmp = (BitSet)_out.clone();
// Traverse the instructions in this basic block in reverse order!
View
41 src/org/jruby/compiler/ir/representations/CFG.java
@@ -156,6 +156,7 @@ private BasicBlock createNewBB(DirectedGraph<BasicBlock, CFG_Edge> g, Map<Label,
private void removeBB(BasicBlock b) {
_cfg.removeVertex(b);
+ _bbMap.remove(b._label);
_bbRescuerMap.remove(b);
// SSS FIXME: Patch up rescued regions as well??
}
@@ -333,11 +334,11 @@ else if (i instanceof BREAK_Instr) {
rr.setFirstRescueBB(firstRescueBB);
// 2. Record a mapping from the region's exclusive basic blocks to the first bb that will start exception handling for all their exceptions.
- for (BasicBlock b: rr._exclusiveBBs)
+ // 3. Add an exception edge from every exclusive bb of the region to firstRescueBB
+ for (BasicBlock b: rr._exclusiveBBs) {
_bbRescuerMap.put(b, firstRescueBB);
-
- // 3. Add an exception edge from the last bb of the region to firstRescueBB
- g.addEdge(rr._endBB, firstRescueBB)._type = CFG_Edge_Type.EXCEPTION_EDGE;
+ g.addEdge(b, firstRescueBB)._type = CFG_Edge_Type.EXCEPTION_EDGE;
+ }
}
// Dummy entry and exit basic blocks and other dummy edges are needed to maintain the CFG
@@ -364,14 +365,17 @@ else if (i instanceof BREAK_Instr) {
g.addEdge(currBB, _exitBB)._type = CFG_Edge_Type.DUMMY_EDGE;
}
+ _cfg = g;
+
+ // Delete orphaned (with no incoming edges) blocks
+ deleteOrphanedBlocks();
+
// Set up the bb array
int n = getMaxNodeID();
_bbArray = new BasicBlock[n];
for (BasicBlock x : _bbMap.values()) {
_bbArray[x.getID() - 1] = x;
}
-
- _cfg = g;
}
private void mergeBBs(BasicBlock a, BasicBlock b) {
@@ -775,6 +779,31 @@ private void pushBBOnStack(Stack<BasicBlock> stack, BitSet bbSet, BasicBlock bb)
}
}
+ public void deleteOrphanedBlocks() {
+ System.out.println("\nGraph:\n" + getGraph().toString());
+ System.out.println("\nInstructions:\n" + toStringInstrs());
+
+ // FIXME: Quick and dirty implementation
+ while (true) {
+ BasicBlock bbToRemove = null;
+ for (BasicBlock b: getNodes()) {
+ // Skip entry bb!
+ if (b == _entryBB)
+ continue;
+
+ // Every other bb should have at least one incoming edge
+ if (incomingEdgesOf(b).size() == 0) {
+ bbToRemove = b;
+ break;
+ }
+ }
+ if (bbToRemove == null)
+ break;
+ else
+ removeBB(bbToRemove);
+ }
+ }
+
public List<BasicBlock> linearize() {
_linearizedBBList = new ArrayList<BasicBlock>();
View
7 src/org/jruby/ext/ffi/MemoryPointer.java
@@ -102,13 +102,6 @@ public final IRubyObject initialize(ThreadContext context,
public final String toString() {
return String.format("MemoryPointer[address=%#x, size=%d]", getAddress(), size);
}
-
- @Override
- @JRubyMethod(name = { "to_s", "inspect" })
- public final IRubyObject inspect(ThreadContext context) {
- return RubyString.newString(context.getRuntime(),
- String.format("#<MemoryPointer address=%#x size=%d>", getAddress(), size));
- }
@JRubyMethod(name = "free")
public final IRubyObject free(ThreadContext context) {
View
14 src/org/jruby/ext/ffi/Pointer.java
@@ -111,17 +111,13 @@ public IRubyObject null_p(ThreadContext context) {
@Override
- @JRubyMethod(name = "to_s", optional = 1)
+ @JRubyMethod(name = { "to_s", "inspect" }, optional = 1)
public IRubyObject to_s(ThreadContext context, IRubyObject[] args) {
- return RubyString.newString(context.getRuntime(),
- String.format("Pointer [address=%x]", getAddress()));
- }
+ String s = size != Long.MAX_VALUE
+ ? String.format("#<%s address=0x%x size=%s>", getMetaClass().getName(), getAddress(), size)
+ : String.format("#<%s address=0x%x>", getMetaClass().getName(), getAddress());
- @JRubyMethod(name = "inspect")
- public IRubyObject inspect(ThreadContext context) {
- String hex = Long.toHexString(getAddress());
- return RubyString.newString(context.getRuntime(),
- String.format("#<Pointer address=0x%s>", hex));
+ return RubyString.newString(context.getRuntime(), s);
}
@JRubyMethod(name = { "address", "to_i" })
View
67 src/org/jruby/ext/ffi/Util.java
@@ -39,7 +39,6 @@
import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.javasupport.JavaObject;
-import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
@@ -50,66 +49,44 @@
public final class Util {
private Util() {}
public static final byte int8Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside char range");
- }
- return (byte) value;
+ return (byte) longValue(parameter);
}
+
public static final short uint8Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < 0 || value > 0xffL) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside unsigned char range");
- }
- return (short) value;
+ return (short) longValue(parameter);
}
+
public static final short int16Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside short range");
- }
- return (short) value;
+ return (short) longValue(parameter);
}
+
public static final int uint16Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < 0 || value > 0xffffL) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside unsigned short range");
- }
- return (int) value;
+ return (int) longValue(parameter);
}
+
public static final int int32Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < Integer.MIN_VALUE || value > 0xffffffffL) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside integer range");
- }
- // This also handles unsigned int -> negative signed int conversion
- return (int) value;
+ return (int) longValue(parameter);
}
+
public static final long uint32Value(IRubyObject parameter) {
- final long value = longValue(parameter);
- if (value < 0 || value > 0xffffffffL) {
- throw parameter.getRuntime().newRangeError("Value "
- + value + " outside unsigned integer range");
- }
- return value;
+ return longValue(parameter);
}
+
public static final long int64Value(IRubyObject parameter) {
return longValue(parameter);
}
+
public static final long uint64Value(IRubyObject parameter) {
final long value = parameter instanceof RubyBignum
? ((RubyBignum) parameter).getValue().longValue()
:longValue(parameter);
return value;
}
+
public static final float floatValue(IRubyObject parameter) {
return (float) RubyNumeric.num2dbl(parameter);
}
+
public static final double doubleValue(IRubyObject parameter) {
return RubyNumeric.num2dbl(parameter);
}
@@ -123,11 +100,14 @@ public static final double doubleValue(IRubyObject parameter) {
public static final long longValue(IRubyObject parameter) {
if (parameter instanceof RubyNumeric) {
return ((RubyNumeric) parameter).getLongValue();
+
} else if (parameter.isNil()) {
return 0L;
+
} else if (parameter instanceof RubyString) {
return longValue((RubyString) parameter);
}
+
throw parameter.getRuntime().newRangeError("Value "
+ parameter + " is not an integer");
}
@@ -139,44 +119,55 @@ private static final long longValue(RubyString parameter) {
throw parameter.getRuntime().newRangeError("Value "
+ parameter + " is not an integer");
}
+
public static final IRubyObject newSigned8(Ruby runtime, byte value) {
return runtime.newFixnum(value);
}
+
public static final IRubyObject newUnsigned8(Ruby runtime, byte value) {
return runtime.newFixnum(value < 0 ? (long)((value & 0x7FL) + 0x80L) : value);
}
+
public static final IRubyObject newSigned16(Ruby runtime, short value) {
return runtime.newFixnum(value);
}
+
public static final IRubyObject newUnsigned16(Ruby runtime, short value) {
return runtime.newFixnum(value < 0 ? (long)((value & 0x7FFFL) + 0x8000L) : value);
}
+
public static final IRubyObject newSigned32(Ruby runtime, int value) {
return runtime.newFixnum(value);
}
+
public static final IRubyObject newUnsigned32(Ruby runtime, int value) {
return runtime.newFixnum(value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value);
}
+
public static final IRubyObject newSigned64(Ruby runtime, long value) {
return runtime.newFixnum(value);
}
+
private static final BigInteger UINT64_BASE = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
public static final IRubyObject newUnsigned64(Ruby runtime, long value) {
return value < 0
? RubyBignum.newBignum(runtime, BigInteger.valueOf(value & 0x7fffffffffffffffL).add(UINT64_BASE))
: runtime.newFixnum(value);
}
+
@Deprecated
public static final <T> T convertParameter(IRubyObject parameter, Class<T> paramClass) {
return paramClass.cast(parameter instanceof JavaObject
? ((JavaObject) parameter).getValue()
: parameter.toJava(paramClass));
}
+
public static final ByteBuffer slice(ByteBuffer buf, int offset) {
ByteBuffer tmp = buf.duplicate();
tmp.position((int) offset);
return tmp.slice();
}
+
public static final void checkStringSafety(Ruby runtime, IRubyObject value) {
RubyString s = value.asString();
if (runtime.getSafeLevel() > 0 && s.isTaint()) {
View
6 src/org/jruby/ext/ffi/jffi/DynamicLibrary.java
@@ -116,12 +116,12 @@ public Symbol(Ruby runtime, DynamicLibrary library, String name, DirectMemoryIO
public IRubyObject library(ThreadContext context) {
return library;
}
-
- @Override
+
@JRubyMethod(name = "inspect")
public IRubyObject inspect(ThreadContext context) {
return RubyString.newString(context.getRuntime(),
- String.format("#<Library:Symbol library=%s symbol=%s address=%#x>", library.name, name, getAddress()));
+ String.format("#<%s library=%s symbol=%s address=%#x>",
+ getMetaClass().getName(), library.name, name, getAddress()));
}
@Override
View
23 src/org/jruby/util/Sprintf.java
@@ -543,7 +543,7 @@ private static boolean rubySprintfToBuffer(ByteList buf, CharSequence charFormat
} else {
negative = ((RubyBignum)arg).getValue().signum() < 0;
zero = ((RubyBignum)arg).getValue().equals(BigInteger.ZERO);
- if (negative && fchar == 'u') {
+ if (negative && fchar == 'u' && usePrefixForZero) {
bytes = getUnsignedNegativeBytes((RubyBignum)arg);
} else {
bytes = getBignumBytes((RubyBignum)arg,base,sign,fchar=='X');
@@ -621,15 +621,22 @@ private static boolean rubySprintfToBuffer(ByteList buf, CharSequence charFormat
if (len < precision) {
if (leadChar == 0) {
- buf.fill('0', precision - len);
+ if (fchar != 'd' || usePrefixForZero || !negative ||
+ ((flags & FLAG_ZERO) != 0 && (flags & FLAG_MINUS) == 0)) {
+ buf.fill('0', precision - len);
+ }
} else if (leadChar == '.') {
buf.fill(leadChar,precision-len);
buf.append(PREFIX_NEGATIVE);
+ } else if (!usePrefixForZero) {
+ buf.append(PREFIX_NEGATIVE);
+ buf.fill(leadChar,precision - len - 1);
} else {
buf.fill(leadChar,precision-len+1); // the 1 is for the stripped sign char
}
} else if (leadChar != 0) {
- if ((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0) {
+ if (((flags & (FLAG_PRECISION | FLAG_ZERO)) == 0 && usePrefixForZero) ||
+ (!usePrefixForZero && "xXbBo".indexOf(fchar) != -1)) {
buf.append(PREFIX_NEGATIVE);
}
if (leadChar != '.') buf.append(leadChar);
@@ -637,6 +644,10 @@ private static boolean rubySprintfToBuffer(ByteList buf, CharSequence charFormat
buf.append(bytes,first,numlen);
if (width > 0) buf.fill(' ',width);
+ if (len < precision && fchar == 'd' && negative && !usePrefixForZero
+ && (flags & FLAG_MINUS) != 0) {
+ buf.fill(' ', precision - len);
+ }
offset++;
incomplete = false;
@@ -652,7 +663,11 @@ private static boolean rubySprintfToBuffer(ByteList buf, CharSequence charFormat
if (!(arg instanceof RubyFloat)) {
// FIXME: what is correct 'recv' argument?
// (this does produce the desired behavior)
- arg = RubyKernel.new_float(arg,arg);
+ if (usePrefixForZero) {
+ arg = RubyKernel.new_float(arg,arg);
+ } else {
+ arg = RubyKernel.new_float19(arg,arg);
+ }
}
double dval = ((RubyFloat)arg).getDoubleValue();
boolean nan = dval != dval;
View
21 src/org/jruby/util/io/ChannelDescriptor.java
@@ -117,6 +117,12 @@
* tell if a channel is "really" seekable.
*/
private boolean canBeSeekable = true;
+
+ /**
+ * In order to avoid closing the JVM's stdio streams, we set a flag here to
+ * indicate that this ChannelDescriptor instance wraps one of those streams.
+ */
+ private final boolean stdio;
/**
* Construct a new ChannelDescriptor with the specified channel, file number,
@@ -138,6 +144,11 @@ private ChannelDescriptor(Channel channel, int fileno, ModeFlags originalModes,
this.originalModes = originalModes;
this.fileDescriptor = fileDescriptor;
this.canBeSeekable = canBeSeekable;
+ this.stdio = (
+ fileDescriptor == FileDescriptor.in ||
+ fileDescriptor == FileDescriptor.out ||
+ fileDescriptor == FileDescriptor.err
+ );
registerDescriptor(this);
}
@@ -800,8 +811,14 @@ public void close() throws BadDescriptorException, IOException {
if (DEBUG) getLogger("ChannelDescriptor").info("Descriptor for fileno " + internalFileno + " refs: " + count);
if (count <= 0) {
- channel.close();
- unregisterDescriptor(internalFileno);
+ try {
+ // we should never close JVM's in, out, or err here
+ if (!stdio) {
+ channel.close();
+ }
+ } finally {
+ unregisterDescriptor(internalFileno);
+ }
}
}
}
View
4 src/org/jruby/util/io/ChannelStream.java
@@ -758,7 +758,6 @@ public synchronized void lseek(long offset, int type) throws IOException, Invali
} catch (IllegalArgumentException e) {
throw new InvalidValueException();
} catch (IOException ioe) {
- ioe.printStackTrace();
throw ioe;
}
} else if (descriptor.getChannel() instanceof SelectableChannel) {
@@ -1147,7 +1146,7 @@ public void finalize() {
}
// FIXME: I got a bunch of NPEs when I didn't check for nulls here...HOW?!
- if (descriptor != null && descriptor.isSeekable() && descriptor.isOpen()) {
+ if (descriptor != null && descriptor.isOpen()) {
closeForFinalize(); // close without removing from finalizers
}
}
@@ -1165,7 +1164,6 @@ public int ready() throws IOException {
ready_stat = sel.selectNow();
sel.close();
} catch (Throwable ex) {
- ex.printStackTrace();
} finally {
if (sel != null) {
try {

0 comments on commit 3e92a39

Please sign in to comment.
Something went wrong with that request. Please try again.