Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Nov 9, 2014
2 parents 8d100c4 + 928acd1 commit 41a6379
Show file tree
Hide file tree
Showing 16 changed files with 324 additions and 190 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -67,7 +67,7 @@ branches:
before_install:
- if [[ $TRAVIS_JDK_VERSION = 'oraclejdk8' ]]; then sudo apt-get update; sudo apt-get install oracle-java8-installer; else true; fi

script: travis_retry mvn install $TARGET -Dinvoker.skip=false | egrep -v 'Download|\\[exec\\] [[:digit:]]+/[[:digit:]]+|^[[:space:]]*\\[exec\\][[:space:]]*$' ; [ ${PIPESTATUS[0]} == 0 ]
script: mvn package && travis_retry mvn install $TARGET -Dinvoker.skip=false | egrep -v 'Download|\\[exec\\] [[:digit:]]+/[[:digit:]]+|^[[:space:]]*\\[exec\\][[:space:]]*$' ; [ ${PIPESTATUS[0]} == 0 ]
install: /bin/true
notifications:
irc:
Expand Down
70 changes: 40 additions & 30 deletions core/src/main/java/org/jruby/RubyIO.java
Expand Up @@ -407,24 +407,37 @@ protected RubyIO reopenIO(ThreadContext context, RubyIO nfile) {
throw runtime.newArgumentError(fptr.PREP_STDIO_NAME() + " can't change access mode from \"" + fptr.getModeAsString(runtime) + "\" to \"" + orig.getModeAsString(runtime) + "\"");
}
}
if (fptr.isWritable()) {
if (fptr.io_fflush(context) < 0)
throw runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
}
else {
fptr.tell(context);
}
if (orig.isReadable()) {
pos = orig.tell(context);
// FIXME: three lock acquires...trying to reduce risk of deadlock, but not sure it's possible.

boolean locked = fptr.lock();
try {
if (fptr.isWritable()) {
if (fptr.io_fflush(context) < 0)
throw runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
} else {
fptr.tell(context);
}
} finally {
if (locked) fptr.unlock();
}
if (orig.isWritable()) {
if (orig.io_fflush(context) < 0)
throw runtime.newErrnoFromErrno(orig.errno(), fptr.getPath());

locked = orig.lock();
try {
if (orig.isReadable()) {
pos = orig.tell(context);
}
if (orig.isWritable()) {
if (orig.io_fflush(context) < 0)
throw runtime.newErrnoFromErrno(orig.errno(), fptr.getPath());
}
} finally {
if (locked) orig.unlock();
}

/* copy rb_io_t structure */
// NOTE: MRI does not copy sync here, but I can find no way to make stdout/stderr stay sync through a reopen
boolean locked = fptr.lock();
locked = fptr.lock();
boolean locked2 = orig.lock(); // TODO: This WILL deadlock if two threads try to reopen the same IOs in opposite directions. Fix?
try {
fptr.setMode(orig.getMode() | (fptr.getMode() & (OpenFile.PREP | OpenFile.SYNC)));
fptr.setProcess(orig.getProcess());
Expand Down Expand Up @@ -467,15 +480,16 @@ protected RubyIO reopenIO(ThreadContext context, RubyIO nfile) {
// TODO: clear interrupts waiting on this IO?
// rb_thread_fd_close(fd);
if (orig.isReadable() && pos >= 0) {
checkReopenSeek(context, runtime, fptr, pos);
checkReopenSeek(context, runtime, orig, pos);
fptr.checkReopenSeek(context, runtime, pos);
orig.checkReopenSeek(context, runtime, pos);
}
}

if (fptr.isBinmode()) {
setBinmode();
}
} finally {
if (locked2) orig.unlock();
if (locked) fptr.unlock();
}

Expand All @@ -484,14 +498,8 @@ protected RubyIO reopenIO(ThreadContext context, RubyIO nfile) {
return this;
}

private void checkReopenSeek(ThreadContext context, Ruby runtime, OpenFile fptr, long pos) {
if (fptr.seek(context, pos, PosixShim.SEEK_SET) < 0 && fptr.errno() != null) {
throw runtime.newErrnoFromErrno(fptr.errno(), fptr.getPath());
}
}

private void checkReopenCloexecDup2(Ruby runtime, OpenFile orig, ChannelFD oldfd, ChannelFD newfd) {
orig.cloexecDup2(runtime, oldfd, newfd);
OpenFile.cloexecDup2(new PosixShim(runtime.getPosix()), oldfd, newfd);
}

// rb_io_binmode
Expand Down Expand Up @@ -627,7 +635,7 @@ public IRubyObject reopen(ThreadContext context, IRubyObject[] args) {
} else {
ChannelFD tmpfd = sysopen(runtime, fptr.getPath(), oflags_p[0], 0666);
Errno err = null;
if (fptr.cloexecDup2(runtime, tmpfd, fptr.fd()) < 0)
if (fptr.cloexecDup2(fptr.posix, tmpfd, fptr.fd()) < 0)
err = fptr.errno();

if (err != null) {
Expand Down Expand Up @@ -1476,11 +1484,11 @@ public RubyBoolean sync(ThreadContext context) {

RubyIO io = GetWriteIO();
fptr = io.getOpenFileChecked();
fptr.lockReadOnly();
fptr.lock();
try {
return (fptr.getMode() & OpenFile.SYNC) != 0 ? runtime.getTrue() : runtime.getFalse();
} finally {
fptr.unlockReadOnly();
fptr.unlock();
}
}

Expand Down Expand Up @@ -1806,13 +1814,13 @@ public RubyBoolean tty_p(ThreadContext context) {

fptr = getOpenFileChecked();

fptr.lockReadOnly();
fptr.lock();
try {
if (fptr.isStdio()) return runtime.getTrue();
if (runtime.getPosix().isNative() && runtime.getPosix().libc().isatty(fptr.getFileno()) != 0)
return runtime.getTrue();
} finally {
fptr.unlockReadOnly();
fptr.unlock();
}

return runtime.getFalse();
Expand All @@ -1836,8 +1844,9 @@ public IRubyObject initialize_copy(IRubyObject _io){
orig = io.getOpenFileChecked();
fptr = dest.MakeOpenFile();

// orig is the visible one here
orig.lockReadOnly();
// orig is the visible one here but we lock both anyway
boolean locked1 = orig.lock();
boolean locked2 = fptr.lock();
try {
io.flush(context);

Expand All @@ -1860,7 +1869,8 @@ public IRubyObject initialize_copy(IRubyObject _io){
if (0 <= pos)
fptr.seek(context, pos, PosixShim.SEEK_SET);
} finally {
orig.unlockReadOnly();
if (locked2) fptr.unlock();
if (locked1) orig.unlock();
}

if (fptr.isBinmode()) {
Expand Down
12 changes: 11 additions & 1 deletion core/src/main/java/org/jruby/RubyRange.java
Expand Up @@ -279,7 +279,7 @@ public IRubyObject call(IRubyObject obj, boolean recur) {
}, value);
}

@JRubyMethod(name = {"inspect", "to_s"})
@JRubyMethod(name = "inspect")
public IRubyObject inspect(final ThreadContext context) {
RubyString i1 = ((RubyString) inspectValue(context, begin)).strDup(context.runtime);
RubyString i2 = (RubyString) inspectValue(context, end);
Expand All @@ -289,6 +289,16 @@ public IRubyObject inspect(final ThreadContext context) {
return i1;
}

@JRubyMethod(name = "to_s")
public IRubyObject to_s(final ThreadContext context) {
RubyString i1 = begin.asString().strDup(context.runtime);
RubyString i2 = end.asString();
i1.cat(isExclusive ? DOTDOTDOT : DOTDOT);
i1.append(i2);
i1.infectBy(i2);
return i1;
}

@JRubyMethod(name = "exclude_end?")
public RubyBoolean exclude_end_p() {
return getRuntime().newBoolean(isExclusive);
Expand Down
11 changes: 8 additions & 3 deletions core/src/main/java/org/jruby/embed/jsr223/Utils.java
Expand Up @@ -177,9 +177,14 @@ private static void setErrorWriter(ScriptingContainer container, Writer writer)
private static RubyIO getRubyIO(Ruby runtime, Writer writer) throws IOException, BadDescriptorException {
PrintStream pstream = new PrintStream(new WriterOutputStream(writer), true);
RubyIO io = new RubyIO(runtime, pstream, false);
io.getOpenFile().setSync(true);
io.getOpenFile().io_fflush(runtime.getCurrentContext());
return io;
boolean locked = io.getOpenFile().lock();
try {
io.getOpenFile().setSync(true);
io.getOpenFile().io_fflush(runtime.getCurrentContext());
return io;
} finally {
if (locked) io.getOpenFile().unlock();
}
}

static void postEval(ScriptingContainer container, ScriptContext context) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -3290,7 +3290,7 @@ public Operand buildSplat(SplatNode splatNode, IRScope s) {
}

public Operand buildStr(StrNode strNode, IRScope s) {
return copyAndReturnValue(s, new StringLiteral(strNode.getValue()));
return copyAndReturnValue(s, new StringLiteral(strNode.getValue(), strNode.getCodeRange()));
}

private Operand buildSuperInstr(IRScope s, Operand block, Operand[] args, int linenumber) {
Expand Down
Expand Up @@ -77,8 +77,8 @@ public Instr clone(CloneInfo ii) {
return new BuildCompoundStringInstr(ii.getRenamedVariable(result), newPieces, encoding);
}

public boolean isSameEncoding(StringLiteral str) {
return str.bytelist.getEncoding() == encoding;
public boolean isSameEncodingAndCodeRange(RubyString str, StringLiteral newStr) {
return newStr.bytelist.getEncoding() == encoding && newStr.getCodeRange() == str.getCodeRange();
}

public RubyString[] retrievePieces(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
Expand All @@ -97,11 +97,12 @@ public Object interpret(ThreadContext context, StaticScope currScope, DynamicSco
bytes.setEncoding(encoding);
RubyString str = RubyString.newStringShared(context.runtime, bytes, StringSupport.CR_7BIT);
for (Operand p : pieces) {
if ((p instanceof StringLiteral) && (isSameEncoding((StringLiteral)p))) {
if ((p instanceof StringLiteral) && (isSameEncodingAndCodeRange(str, (StringLiteral)p))) {
str.getByteList().append(((StringLiteral)p).bytelist);
str.setCodeRange(str.scanForCodeRange());
} else {
IRubyObject pval = (IRubyObject)p.retrieve(context, self, currScope, currDynScope, temp);
str.append19(pval);
IRubyObject pval = (IRubyObject)p.retrieve(context, self, currScope, currDynScope, temp);
str.append19(pval);
}
}

Expand Down
12 changes: 11 additions & 1 deletion core/src/main/java/org/jruby/ir/operands/StringLiteral.java
Expand Up @@ -9,6 +9,7 @@
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.StringSupport;

import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
Expand All @@ -25,11 +26,17 @@ public class StringLiteral extends Operand {

final public ByteList bytelist;
final public String string;
final public int coderange;

public StringLiteral(ByteList val) {
this(val, StringSupport.CR_7BIT);
}

public StringLiteral(ByteList val, int coderange) {
super(OperandType.STRING_LITERAL);

bytelist = val;
this.coderange = coderange;
String stringTemp;
try {
stringTemp = Helpers.byteListToString(bytelist);
Expand All @@ -43,11 +50,12 @@ public StringLiteral(String s) {
this(s, ByteList.create(s));
}

private StringLiteral(String string, ByteList byteList ) {
private StringLiteral(String string, ByteList byteList) {
super(OperandType.STRING_LITERAL);

this.bytelist = byteList;
this.string = string;
this.coderange = StringSupport.CR_7BIT;
}

@Override
Expand Down Expand Up @@ -98,4 +106,6 @@ public ByteList getByteList() {
public String getString() {
return string;
}

public int getCodeRange() { return coderange; }
}
14 changes: 7 additions & 7 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Expand Up @@ -732,13 +732,13 @@ public void BuildCompoundStringInstr(BuildCompoundStringInstr compoundstring) {
csByteList.setEncoding(compoundstring.getEncoding());
jvmMethod().pushString(csByteList);
for (Operand p : compoundstring.getPieces()) {
if ((p instanceof StringLiteral) && (compoundstring.isSameEncoding((StringLiteral)p))) {
jvmMethod().pushByteList(((StringLiteral)p).bytelist);
jvmAdapter().invokevirtual(p(RubyString.class), "cat", sig(RubyString.class, ByteList.class));
} else {
// if ((p instanceof StringLiteral) && (compoundstring.isSameEncodingAndCodeRange((StringLiteral)p))) {
// jvmMethod().pushByteList(((StringLiteral)p).bytelist);
// jvmAdapter().invokevirtual(p(RubyString.class), "cat", sig(RubyString.class, ByteList.class));
// } else {
visit(p);
jvmAdapter().invokevirtual(p(RubyString.class), "append19", sig(RubyString.class, IRubyObject.class));
}
// }
}
jvmStoreLocal(compoundstring.getResult());
}
Expand Down Expand Up @@ -1507,7 +1507,7 @@ public void ReqdArgMultipleAsgnInstr(ReqdArgMultipleAsgnInstr reqdargmultipleasg
jvmAdapter().pushInt(reqdargmultipleasgninstr.getPreArgsCount());
jvmAdapter().pushInt(reqdargmultipleasgninstr.getIndex());
jvmAdapter().pushInt(reqdargmultipleasgninstr.getPostArgsCount());
jvmMethod().invokeHelper("irReqdArgMultipleAsgn", IRubyObject.class, ThreadContext.class, RubyArray.class, int.class, int.class, int.class);
jvmMethod().invokeIRHelper("irReqdArgMultipleAsgn", sig(IRubyObject.class, ThreadContext.class, RubyArray.class, int.class, int.class, int.class));
jvmStoreLocal(reqdargmultipleasgninstr.getResult());
}

Expand Down Expand Up @@ -1729,7 +1729,7 @@ public void ThrowExceptionInstr(ThrowExceptionInstr throwexceptioninstr) {
public void ToAryInstr(ToAryInstr toaryinstr) {
jvmMethod().loadContext();
visit(toaryinstr.getArrayArg());
jvmMethod().invokeHelper("irToAry", IRubyObject.class, ThreadContext.class, IRubyObject.class);
jvmMethod().invokeIRHelper("irToAry", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class));
jvmStoreLocal(toaryinstr.getResult());
}

Expand Down

0 comments on commit 41a6379

Please sign in to comment.