Skip to content

Commit

Permalink
Showing 2 changed files with 28 additions and 56 deletions.
76 changes: 20 additions & 56 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -45,6 +45,7 @@
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.JavaSites.IOSites;
import org.jruby.runtime.callsite.RespondToCallSite;
import org.jruby.util.StringSupport;
import org.jruby.util.io.ChannelFD;
import org.jruby.util.io.EncodingUtils;
@@ -910,7 +911,7 @@ private IRubyObject initializeCommon(ThreadContext context, ChannelFD fd, IRubyO
int ofmode;
int[] oflags_p = {ModeFlags.RDONLY};

if(opt != null && !opt.isNil() && !(opt instanceof RubyHash) && !(opt.respondsTo("to_hash"))) {
if(opt != null && !opt.isNil() && !(opt instanceof RubyHash) && !(sites(context).respond_to_to_hash.respondsTo(context, opt, opt))) {
throw runtime.newArgumentError("last argument must be a hash!");
}

@@ -1425,7 +1426,7 @@ public IRubyObject write(ThreadContext context, IRubyObject str, boolean nosync)
tmp = TypeConverter.ioCheckIO(runtime, io);
if (tmp.isNil()) {
/* port is not IO, call write method for it. */
return io.callMethod(context, "write", str);
return sites(context).write.call(context, io, io, str);
}
io = (RubyIO)tmp;
if (((RubyString)str).size() == 0) return RubyFixnum.zero(runtime);
@@ -1452,7 +1453,7 @@ public IRubyObject write(ThreadContext context, IRubyObject str, boolean nosync)
@JRubyMethod(name = "<<", required = 1)
public IRubyObject op_append(ThreadContext context, IRubyObject anObject) {
// Claims conversion is done via 'to_s' in docs.
callMethod(context, "write", anObject);
sites(context).write.call(context, this, this, anObject);

return this;
}
@@ -1627,7 +1628,7 @@ public static IRubyObject putc(ThreadContext context, IRubyObject maybeIO, IRuby
} else {
byte c = RubyNumeric.num2chr(object);
IRubyObject str = RubyString.newStringShared(context.runtime, RubyFixnum.SINGLE_CHAR_BYTELISTS19[c & 0xFF]);
maybeIO.callMethod(context, "write", str);
sites(context).write.call(context, maybeIO, maybeIO, str);
}

return object;
@@ -3303,7 +3304,7 @@ private static IRubyObject foreachInternal19(ThreadContext context, IRubyObject

// io_s_foreach

IRubyObject[] methodArguments = processReadlinesMethodArguments(args);
IRubyObject[] methodArguments = processReadlinesMethodArguments(context, args);

try {
IRubyObject str;
@@ -3350,7 +3351,7 @@ public static IRubyObject select(ThreadContext context, IRubyObject recv, IRubyO
}
else {
try { // MRI calls to_f even if not respond_to? (or respond_to_missing?) :to_f
_timeout = _timeout.callMethod(context, "to_f");
_timeout = sites(context).to_f.call(context, _timeout, _timeout);
}
catch (RaiseException e) {
TypeConverter.handleUncoercibleObject(true, _timeout, context.runtime.getFloat());
@@ -3487,45 +3488,6 @@ public static IRubyObject ioOpen(ThreadContext context, IRubyObject filename, IR
return ((RubyFile) runtime.getFile().allocate()).fileOpenGeneric(context, filename, oflags_p[0], fmode_p[0], convconfig, perm);
}

/**
* options is a hash which can contain:
* encoding: string or encoding
* mode: string
* open_args: array of string
*/
/*
private static IRubyObject write19(ThreadContext context, IRubyObject recv, IRubyObject path, IRubyObject str, IRubyObject offset, RubyHash options) {
Ruby runtime = context.runtime;
RubyString pathStr = StringSupport.checkEmbeddedNulls(runtime, RubyFile.get_path(context, path));
failIfDirectory(runtime, pathStr);
final RubyIO file;
long mode = ModeFlags.CREAT;
if (options == null || options.isEmpty()) {
if (offset.isNil()) {
mode |= ModeFlags.WRONLY;
} else {
mode |= ModeFlags.RDWR;
}
file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, RubyFixnum.newFixnum(runtime, mode));
} else if (!options.containsKey(runtime.newSymbol("mode"))) {
mode |= ModeFlags.WRONLY;
file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, RubyFixnum.newFixnum(runtime, mode), options);
} else {
file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, options);
}
try {
if (!offset.isNil()) file.seek(context, offset);
return file.write(context, str);
} finally {
file.close();
}
} */

/**
* binread is just like read, except it doesn't take options and it forces
* mode to be "rb:ASCII-8BIT"
@@ -3549,7 +3511,8 @@ public static IRubyObject binread(ThreadContext context, IRubyObject recv, IRuby
} else if (args.length > 1) {
length = args[1];
}
RubyIO file = (RubyIO) Helpers.invoke(context, runtime.getFile(), "new", path, runtime.newString("rb:ASCII-8BIT"));
RubyClass File = runtime.getFile();
RubyIO file = (RubyIO) sites(context).new_.call(context, File, File, path, runtime.newString("rb:ASCII-8BIT"));

try {
if (!offset.isNil()) {
@@ -3692,18 +3655,19 @@ public static IRubyObject readlines19(ThreadContext context, IRubyObject recv, I
IRubyObject io = openKeyArgs(context, recv, args, opt);
if (io.isNil()) return io;

IRubyObject[] methodArguments = processReadlinesMethodArguments(args);
IRubyObject[] methodArguments = processReadlinesMethodArguments(context, args);

return readlinesCommon19(context, (RubyIO)io, methodArguments);
}

private static IRubyObject[] processReadlinesMethodArguments(IRubyObject[] args) {
private static IRubyObject[] processReadlinesMethodArguments(ThreadContext context, IRubyObject[] args) {
int count = args.length;
IRubyObject[] methodArguments = IRubyObject.NULL_ARRAY;

if(count >= 3 && (args[2] instanceof RubyFixnum || args[2].respondsTo("to_int"))) {
RespondToCallSite respond_to_to_int = sites(context).respond_to_to_int;
if(count >= 3 && (args[2] instanceof RubyFixnum || respond_to_to_int.respondsTo(context, args[2], args[2]))) {
methodArguments = new IRubyObject[]{args[1], args[2]};
} else if (count >= 2 && (args[1] instanceof RubyFixnum || args[1].respondsTo("to_int"))) {
} else if (count >= 2 && (args[1] instanceof RubyFixnum || respond_to_to_int.respondsTo(context, args[1], args[1]))) {
methodArguments = new IRubyObject[]{args[1]};
} else if (count >= 2 && !(args[1] instanceof RubyHash)) {
methodArguments = new IRubyObject[]{args[1]};
@@ -4075,11 +4039,11 @@ public static IRubyObject copy_stream(ThreadContext context, IRubyObject recv, I
RubyString path = (RubyString) TypeConverter.convertToType19(context, arg1, runtime.getString(), sites.to_path_checked1);
io1 = (RubyIO) RubyFile.open(context, runtime.getFile(), new IRubyObject[]{path}, Block.NULL_BLOCK);
close1 = true;
} else if (arg1.respondsTo("read")) {
} else if (sites.respond_to_read.respondsTo(context, arg1, arg1, true)) {
if (length == null) {
read = arg1.callMethod(context, "read", runtime.getNil()).convertToString();
read = sites.read.call(context, arg1, arg1, context.nil).convertToString();
} else {
read = arg1.callMethod(context, "read", length).convertToString();
read = sites.read.call(context, arg1, arg1, length).convertToString();
}
} else {
throw runtime.newArgumentError("Should be String or IO");
@@ -4094,15 +4058,15 @@ public static IRubyObject copy_stream(ThreadContext context, IRubyObject recv, I
RubyString path = (RubyString) TypeConverter.convertToType19(context, arg2, runtime.getString(), sites.to_path_checked2);
io2 = (RubyIO) RubyFile.open(context, runtime.getFile(), new IRubyObject[]{path, runtime.newString("w")}, Block.NULL_BLOCK);
close2 = true;
} else if (arg2.respondsTo("write")) {
} else if (sites.respond_to_write.respondsTo(context, arg2, arg2, true)) {
if (read == null) {
if (length == null) {
read = io1.read(context, runtime.getNil()).convertToString();
} else {
read = io1.read(context, length).convertToString();
}
}
return arg2.callMethod(context, "write", read);
return sites.write.call(context, arg2, arg2, read);
} else {
throw runtime.newArgumentError("Should be String or IO");
}
@@ -4269,7 +4233,7 @@ private static long transfer(ThreadContext context, ReadableByteChannel from, Wr

@JRubyMethod(name = "try_convert", meta = true)
public static IRubyObject tryConvert(ThreadContext context, IRubyObject recv, IRubyObject arg) {
return arg.respondsTo("to_io") ? convertToIO(context, arg) : context.runtime.getNil();
return sites(context).respond_to_to_io.respondsTo(context, arg, arg, true) ? convertToIO(context, arg) : context.runtime.getNil();
}

private static ByteList getNilByteList(Ruby runtime) {
8 changes: 8 additions & 0 deletions core/src/main/java/org/jruby/runtime/JavaSites.java
Original file line number Diff line number Diff line change
@@ -279,7 +279,15 @@ public static class IOSites {
public final CheckedSites close_checked = new CheckedSites("close");
public final CheckedSites to_path_checked1 = new CheckedSites("to_path");
public final CheckedSites to_path_checked2 = new CheckedSites("to_path");
public final RespondToCallSite respond_to_write = new RespondToCallSite("write");
public final CallSite write = new FunctionalCachingCallSite("write");
public final RespondToCallSite respond_to_read = new RespondToCallSite("read");
public final CallSite read = new FunctionalCachingCallSite("read");
public final CallSite to_f = new FunctionalCachingCallSite("to_f");
public final CallSite new_ = new FunctionalCachingCallSite("new");
public final RespondToCallSite respond_to_to_int = new RespondToCallSite("to_int");
public final RespondToCallSite respond_to_to_io = new RespondToCallSite("to_io");
public final RespondToCallSite respond_to_to_hash = new RespondToCallSite("to_hash");
}

public static class TypeConverterSites {

0 comments on commit 9167f3a

Please sign in to comment.