Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 63c5d872f7ea
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dd0b88e44efe
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Jul 7, 2017

  1. make sure encoding is not changing for a shared byte-list

    ... instead share at buffer level when encoding differs from the one set
    kares committed Jul 7, 2017
    Copy the full SHA
    2a54296 View commit details
  2. Copy the full SHA
    64dec94 View commit details
  3. Copy the full SHA
    dd0b88e View commit details
49 changes: 24 additions & 25 deletions core/src/main/java/org/jruby/RubyComplex.java
Original file line number Diff line number Diff line change
@@ -985,16 +985,19 @@ public IRubyObject rationalize(ThreadContext context, IRubyObject[] args) {
}
return real.callMethod(context, "rationalize", args);
}


private static final ByteList SEP = RubyFile.SLASH;
private static final ByteList _eE = new ByteList(new byte[] { '.', 'e', 'E' }, false);

static RubyArray str_to_c_internal(ThreadContext context, IRubyObject recv) {
RubyString s = recv.convertToString();
ByteList bytes = s.getByteList();

Ruby runtime = context.runtime;
if (bytes.getRealSize() == 0) return runtime.newArray(runtime.getNil(), recv);
if (bytes.getRealSize() == 0) return runtime.newArray(context.nil, recv);

IRubyObject sr, si, re;
sr = si = re = runtime.getNil();
sr = si = re = context.nil;
boolean po = false;
IRubyObject m = RubyRegexp.newDummyRegexp(runtime, Numeric.ComplexPatterns.comp_pat0).match_m(context, s, false);

@@ -1024,15 +1027,15 @@ static RubyArray str_to_c_internal(ThreadContext context, IRubyObject recv) {

if (m.isNil()) {
m = RubyRegexp.newDummyRegexp(runtime, Numeric.ComplexPatterns.comp_pat2).match_m(context, s, false);
if (m.isNil()) return runtime.newArray(runtime.getNil(), recv);
if (m.isNil()) return runtime.newArray(context.nil, recv);
RubyMatchData match = (RubyMatchData)m;
sr = match.at(1);
if (match.at(2).isNil()) {
si = runtime.getNil();
si = context.nil;
} else {
si = match.at(3);
IRubyObject t = match.at(4);
if (t.isNil()) t = runtime.newString(RubyFixnum.SINGLE_CHAR_BYTELISTS19['1']);
if (t.isNil()) t = runtime.newString(RubyInteger.singleCharByteList((byte) '1'));
si.convertToString().cat(t.convertToString().getByteList());
}
re = match.post_match(context);
@@ -1042,28 +1045,24 @@ static RubyArray str_to_c_internal(ThreadContext context, IRubyObject recv) {
IRubyObject r = RubyFixnum.zero(runtime);
IRubyObject i = r;

if (!sr.isNil()) {
if (sr.callMethod(context, "include?", runtime.newString(new ByteList(new byte[]{'/'}))).isTrue()) {
r = f_to_r(context, sr);
} else if (f_gt_p(context, sr.callMethod(context, "count", runtime.newString(".eE")), RubyFixnum.zero(runtime)).isTrue()) {
r = f_to_f(context, sr);
} else {
r = f_to_i(context, sr);
}
}
r = convertString(context, sr, r);
i = convertString(context, si, i);

if (!si.isNil()) {
if (si.callMethod(context, "include?", runtime.newString(new ByteList(new byte[]{'/'}))).isTrue()) {
i = f_to_r(context, si);
} else if (f_gt_p(context, si.callMethod(context, "count", runtime.newString(".eE")), RubyFixnum.zero(runtime)).isTrue()) {
i = f_to_f(context, si);
} else {
i = f_to_i(context, si);
}
}
return runtime.newArray(po ? newComplexPolar(context, r, i) : newComplexCanonicalize(context, r, i), re);
}


private static IRubyObject convertString(ThreadContext context, final IRubyObject s, IRubyObject def) {
if (s == context.nil) return def;
final Ruby runtime = context.runtime;
if (s.callMethod(context, "include?", RubyString.newStringShared(runtime, SEP)).isTrue()) {
return f_to_r(context, s);
}
if (f_gt_p(context, s.callMethod(context, "count", RubyString.newStringShared(runtime, _eE)), RubyFixnum.zero(runtime)).isTrue()) {
return f_to_f(context, s);
}
return f_to_i(context, s);
}

private static IRubyObject str_to_c_strict(ThreadContext context, IRubyObject recv) {
RubyArray a = str_to_c_internal(context, recv);
if (a.eltInternal(0).isNil() || a.eltInternal(1).convertToString().getByteList().length() > 0) {
10 changes: 7 additions & 3 deletions core/src/main/java/org/jruby/RubyFile.java
Original file line number Diff line number Diff line change
@@ -92,6 +92,10 @@
**/
@JRubyClass(name="File", parent="IO", include="FileTest")
public class RubyFile extends RubyIO implements EncodingCapable {

static final ByteList SLASH = new ByteList(new byte[] { '/' }, false);
static final ByteList BACKSLASH = new ByteList(new byte[] { '\\' }, false);

public static RubyClass createFileClass(Ruby runtime) {
ThreadContext context = runtime.getCurrentContext();

@@ -107,13 +111,13 @@ public static RubyClass createFileClass(Ruby runtime) {
fileClass.kindOf = new RubyModule.JavaClassKindOf(RubyFile.class);

// file separator constants
RubyString separator = RubyString.newString(runtime, new ByteList(new byte[] { '/' }, false));
RubyString separator = RubyString.newString(runtime, SLASH);
separator.freeze(context);
fileClass.defineConstant("SEPARATOR", separator);
fileClass.defineConstant("Separator", separator);

if (File.separatorChar == '\\') {
RubyString altSeparator = RubyString.newString(runtime, new ByteList(new byte[] { '\\' }, false));
RubyString altSeparator = RubyString.newString(runtime, BACKSLASH);
altSeparator.freeze(context);
fileClass.defineConstant("ALT_SEPARATOR", altSeparator);
} else {
@@ -1153,7 +1157,7 @@ public static IRubyObject utime(ThreadContext context, IRubyObject recv, IRubyOb
long[] atimeval = null;
long[] mtimeval = null;

if (args[0] != runtime.getNil() || args[1] != runtime.getNil()) {
if (args[0] != context.nil || args[1] != context.nil) {
atimeval = extractTimeval(context, args[0]);
mtimeval = extractTimeval(context, args[1]);
}
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/RubyIO.java
Original file line number Diff line number Diff line change
@@ -1627,9 +1627,9 @@ public IRubyObject printf(ThreadContext context, IRubyObject[] args) {
public IRubyObject putc(ThreadContext context, IRubyObject ch) {
IRubyObject str;
if (ch instanceof RubyString) {
str = ((RubyString)ch).substr(context.runtime, 0, 1);
str = ((RubyString) ch).substr(context.runtime, 0, 1);
} else {
str = RubyString.newStringShared(context.runtime, RubyFixnum.SINGLE_CHAR_BYTELISTS19[RubyNumeric.num2chr(ch) & 0xFF]);
str = RubyString.newStringShared(context.runtime, RubyInteger.singleCharByteList(RubyNumeric.num2chr(ch)));
}

sites(context).write.call(context, this, this, str);
@@ -1639,10 +1639,10 @@ public IRubyObject putc(ThreadContext context, IRubyObject ch) {

public static IRubyObject putc(ThreadContext context, IRubyObject maybeIO, IRubyObject object) {
if (maybeIO instanceof RubyIO) {
((RubyIO)maybeIO).putc(context, object);
((RubyIO) maybeIO).putc(context, object);
} else {
byte c = RubyNumeric.num2chr(object);
IRubyObject str = RubyString.newStringShared(context.runtime, RubyFixnum.SINGLE_CHAR_BYTELISTS19[c & 0xFF]);
IRubyObject str = RubyString.newStringShared(context.runtime, RubyInteger.singleCharByteList(c));
sites(context).write.call(context, maybeIO, maybeIO, str);
}

29 changes: 14 additions & 15 deletions core/src/main/java/org/jruby/RubyInteger.java
Original file line number Diff line number Diff line change
@@ -300,20 +300,20 @@ public IRubyObject succ(ThreadContext context) {
}

static final ByteList[] SINGLE_CHAR_BYTELISTS;
@Deprecated
public static final ByteList[] SINGLE_CHAR_BYTELISTS19;
static {
SINGLE_CHAR_BYTELISTS = new ByteList[256];
SINGLE_CHAR_BYTELISTS19 = new ByteList[256];
for (int i = 0; i < 256; i++) {
ByteList usascii = new ByteList(new byte[]{(byte)i}, false);
SINGLE_CHAR_BYTELISTS[i] = usascii;
SINGLE_CHAR_BYTELISTS19[i] = i < 0x80 ?
new ByteList(new byte[]{(byte)i}, USASCIIEncoding.INSTANCE)
:
new ByteList(
new byte[]{(byte)i},
ASCIIEncoding.INSTANCE);
ByteList bytes = new ByteList(new byte[] { (byte) i }, false);
SINGLE_CHAR_BYTELISTS[i] = bytes;
bytes.setEncoding(i < 0x80 ? USASCIIEncoding.INSTANCE : ASCIIEncoding.INSTANCE);
}
SINGLE_CHAR_BYTELISTS19 = SINGLE_CHAR_BYTELISTS;
}

static ByteList singleCharByteList(final byte index) {
return SINGLE_CHAR_BYTELISTS[index & 0xFF];
}

/** int_chr
@@ -322,18 +322,17 @@ public IRubyObject succ(ThreadContext context) {
@JRubyMethod(name = "chr")
public RubyString chr(ThreadContext context) {
Ruby runtime = context.runtime;
int value = (int)getLongValue();
int value = (int) getLongValue();
if (value >= 0 && value <= 0xFF) {
ByteList bytes = SINGLE_CHAR_BYTELISTS19[value];
ByteList bytes = SINGLE_CHAR_BYTELISTS[value];
return RubyString.newStringShared(runtime, bytes, bytes.getEncoding());
} else {
Encoding enc = runtime.getDefaultInternalEncoding();
if (value > 0xFF && (enc == null || enc == ASCIIEncoding.INSTANCE)) {
throw runtime.newRangeError(this.toString() + " out of char range");
} else {
if (enc == null) enc = USASCIIEncoding.INSTANCE;
return RubyString.newStringNoCopy(runtime, fromEncodedBytes(runtime, enc, value), enc, 0);
throw runtime.newRangeError(toString() + " out of char range");
}
if (enc == null) enc = USASCIIEncoding.INSTANCE;
return RubyString.newStringNoCopy(runtime, fromEncodedBytes(runtime, enc, value), enc, 0);
}
}

20 changes: 12 additions & 8 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -572,8 +572,15 @@ public static RubyString newStringShared(Ruby runtime, RubyClass clazz, ByteList
}

public static RubyString newStringShared(Ruby runtime, RubyClass clazz, ByteList bytes, Encoding encoding) {
RubyString str = new RubyString(runtime, clazz, bytes, encoding);
str.shareLevel = SHARE_LEVEL_BYTELIST;
if (bytes.getEncoding() == encoding) return newStringShared(runtime, clazz, bytes);
RubyString str = new RubyString(runtime, clazz, bytes.makeShared(bytes.getBegin(), bytes.getRealSize()), encoding);
str.shareLevel = SHARE_LEVEL_BUFFER; // since passing an encoding in does bytes.setEncoding(encoding)
return str;
}

private static RubyString newStringShared(Ruby runtime, ByteList bytes, Encoding encoding, int cr) {
RubyString str = newStringShared(runtime, runtime.getString(), bytes, encoding);
str.flags |= cr;
return str;
}

@@ -813,8 +820,7 @@ public final RubyString makeShared(Ruby runtime, RubyClass meta, int index, int
if (len == 0) {
shared = newEmptyString(runtime, meta);
} else if (len == 1) {
shared = newStringShared(runtime, meta,
RubyInteger.SINGLE_CHAR_BYTELISTS[value.getUnsafeBytes()[value.getBegin() + index] & 0xff]);
shared = newStringShared(runtime, meta, RubyInteger.singleCharByteList(value.getUnsafeBytes()[value.getBegin() + index]));
} else {
if (shareLevel == SHARE_LEVEL_NONE) shareLevel = SHARE_LEVEL_BUFFER;
shared = new RubyString(runtime, meta, value.makeShared(index, len));
@@ -3272,10 +3278,8 @@ final IRubyObject uptoCommon(ThreadContext context, IRubyObject arg, boolean exc
byte e = end.value.getUnsafeBytes()[end.value.getBegin()];
if (c > e || (excl && c == e)) return this;
while (true) {
ByteList s = RubyInteger.SINGLE_CHAR_BYTELISTS[c & 0xff];
RubyString str = new RubyString(runtime, runtime.getString(), s, enc, CR_7BIT);
str.shareLevel = SHARE_LEVEL_BYTELIST;
block.yield(context, asSymbol ? runtime.newSymbol(s) : str);
ByteList s = RubyInteger.singleCharByteList(c);
block.yield(context, asSymbol ? runtime.newSymbol(s) : newStringShared(runtime, s, enc, CR_7BIT));

if (!excl && c == e) break;
c++;