Skip to content

Commit

Permalink
[Truffle] Avoid converting Ropes to ByteLists in Psych::Parser.
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Dec 24, 2016
1 parent eb8b2c9 commit 963d69a
Showing 1 changed file with 18 additions and 25 deletions.
Expand Up @@ -62,10 +62,9 @@
import org.jruby.truffle.core.cast.ToStrNode;
import org.jruby.truffle.core.cast.ToStrNodeGen;
import org.jruby.truffle.core.rope.CodeRange;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.ByteList;
import org.jruby.truffle.core.string.EncodingUtils;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.core.string.StringSupport;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.SnippetNode;
Expand Down Expand Up @@ -153,8 +152,8 @@ public Object parse(
if (!RubyGuards.isRubyString(yaml) && respondToReadNode.doesRespondTo(frame, "read", yaml)) {
reader = newStreamReader(yaml);
} else {
ByteList byteList = StringOperations.getByteListReadOnly(toStrNode.executeToStr(frame, yaml));
reader = newStringReader(byteList);
Rope rope = StringOperations.rope(toStrNode.executeToStr(frame, yaml));
reader = newStringReader(rope);
}

final Parser parser = newParser(reader);
Expand Down Expand Up @@ -308,19 +307,19 @@ private StreamReader newStreamReader(DynamicObject yaml) {
}

@TruffleBoundary
private StreamReader newStringReader(ByteList byteList) {
Encoding encoding = byteList.getEncoding();
private StreamReader newStringReader(Rope rope) {
Encoding encoding = rope.getEncoding();

if (!(encoding instanceof UnicodeEncoding)) {
byteList = strConvEnc(getContext(), byteList, encoding);
rope = strConvEnc(getContext(), rope, encoding);

encoding = UTF8Encoding.INSTANCE;
}

return new StreamReader(
new InputStreamReader(
new ByteArrayInputStream(
byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize()),
rope.getBytes(), 0, rope.byteLength()),
encoding.getCharset()));
}

Expand Down Expand Up @@ -440,38 +439,36 @@ private Object stringFor(String value, boolean tainted, TaintNode taintNode) {
return string;
}

private ByteList strConvEnc(RubyContext context, ByteList byteList, Encoding encoding) {
return strConvEnc2(context, byteList, encoding, UTF8Encoding.INSTANCE);
private Rope strConvEnc(RubyContext context, Rope rope, Encoding encoding) {
return strConvEnc2(context, rope, encoding, UTF8Encoding.INSTANCE);
}

private static ByteList strConvEnc2(RubyContext context, ByteList value, Encoding fromEncoding, Encoding toEncoding) {
private static Rope strConvEnc2(RubyContext context, Rope value, Encoding fromEncoding, Encoding toEncoding) {
return strConvEncOpts(context, value, fromEncoding, toEncoding, 0, null);
}

private static ByteList strConvEncOpts(RubyContext context, ByteList str, Encoding fromEncoding,
private static Rope strConvEncOpts(RubyContext context, Rope str, Encoding fromEncoding,
Encoding toEncoding, int ecflags, Object ecopts) {
if (toEncoding == null) return str;
if (fromEncoding == null) fromEncoding = str.getEncoding();
if (fromEncoding == toEncoding) return str;
if ((toEncoding.isAsciiCompatible() && isAsciiOnly(str)) ||
toEncoding == ASCIIEncoding.INSTANCE) {
if (str.getEncoding() != toEncoding) {
str = str.dup();
str.setEncoding(toEncoding);
return str.withEncoding(toEncoding, CodeRange.CR_7BIT);
}
return str;
}

ByteList strByteList = str;
int len = strByteList.getRealSize();
int len = str.byteLength();
ByteList newStr = new ByteList(len);
int olen = len;

EConv ec = econvOpenOpts(context, fromEncoding, toEncoding, ecflags, ecopts);
if (ec == null) return str;

byte[] sbytes = strByteList.getUnsafeBytes();
Ptr sp = new Ptr(strByteList.getBegin());
byte[] sbytes = str.getBytes();
Ptr sp = new Ptr(0);
int start = sp.p;

byte[] destbytes;
Expand Down Expand Up @@ -512,7 +509,7 @@ private static ByteList strConvEncOpts(RubyContext context, ByteList str, Encodi
len = dp.p;
newStr.setRealSize(len);
newStr.setEncoding(toEncoding);
return newStr;
return StringOperations.ropeFromByteList(newStr);

default:
// some error, return original
Expand All @@ -525,12 +522,8 @@ private static EConv econvOpenOpts(RubyContext context, Encoding sourceEncoding,
return ec;
}

private static boolean isAsciiOnly(ByteList string) {
return string.getEncoding().isAsciiCompatible() && scanForCodeRange(string) == CodeRange.CR_7BIT;
}

private static CodeRange scanForCodeRange(ByteList string) {
return StringSupport.codeRangeScan(EncodingUtils.getActualEncoding(string.getEncoding(), string), string);
private static boolean isAsciiOnly(Rope string) {
return string.getEncoding().isAsciiCompatible() && string.getCodeRange() == CodeRange.CR_7BIT;
}

}
Expand Down

0 comments on commit 963d69a

Please sign in to comment.