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: 36888b9b5d99
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b03562ba7b9d
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Mar 31, 2015

  1. Copy the full SHA
    e608049 View commit details
  2. Copy the full SHA
    b03562b View commit details
Showing with 42 additions and 47 deletions.
  1. +0 −20 spec/truffle/tags/core/string/element_set_tags.txt
  2. +42 −27 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/StringPrimitiveNodes.java
20 changes: 0 additions & 20 deletions spec/truffle/tags/core/string/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
fails:String#[]= with Fixnum index calls #to_int to convert the index
fails:String#[]= with String index replaces multibyte characters with characters
fails:String#[]= with String index replaces multibyte characters with multibyte characters
fails:String#[]= with a Regexp index replaces characters with a multibyte character
fails:String#[]= with a Regexp index replaces multibyte characters with characters
fails:String#[]= with a Regexp index replaces multibyte characters with multibyte characters
fails:String#[]= with Fixnum index, count replaces characters with a multibyte character
fails:String#[]= with Fixnum index, count replaces multibyte characters with characters
fails:String#[]= with Fixnum index, count replaces multibyte characters with multibyte characters
fails:String#[]= with Fixnum index, count deletes a multibyte character
fails:String#[]= with Fixnum index, count inserts a multibyte character
fails:String#[]= with Fixnum index, count raises an Encoding::CompatibilityError if the replacement encoding is incompatible
fails:String#[]= with Fixnum index replaces a character with a multibyte character
fails:String#[]= with Fixnum index replaces a multibyte character with a character
fails:String#[]= with Fixnum index replaces a multibyte character with a multibyte character
fails:String#[]= with Fixnum index raises an Encoding::CompatibilityError if the replacement encoding is incompatible
fails:String#[]= with a Range index replaces characters with a multibyte character
fails:String#[]= with a Range index replaces multibyte characters with characters
fails:String#[]= with a Range index replaces multibyte characters by negative indexes
fails:String#[]= with a Range index replaces multibyte characters with multibyte characters
fails:String#[]= with a Range index deletes a multibyte character
fails:String#[]= with a Range index inserts a multibyte character
fails:String#[]= with a Range index raises an Encoding::CompatibilityError if the replacement encoding is incompatible
Original file line number Diff line number Diff line change
@@ -675,31 +675,38 @@ public StringByteIndexPrimitiveNode(StringByteIndexPrimitiveNode prev) {
}

@Specialization
public Object stringByteIndex(RubyString string, int characters, int start) {
if (string.getByteList().getEncoding().isSingleByte()) {
return characters - start;
} else {
final Encoding encoding = string.getByteList().getEncoding();
final int length = string.getByteList().length();
public Object stringByteIndex(RubyString string, int index, int start) {
// Taken from Rubinius's String::byte_index.

int count = 0;
final ByteList bytes = string.getByteList();

int i;
final Encoding enc = bytes.getEncoding();
int p = bytes.getBegin();
final int e = p + bytes.getRealSize();

for(i = 0; i < characters && count < length; i++) {
if(!encoding.isMbcHead(string.getByteList().getUnsafeBytes(), count, length)) {
count++;
} else {
count += encoding.codeToMbcLength(string.getByteList().getUnsafeBytes()[count]);
}
}
int i, k = index;

if(i < characters) {
return nil();
if (k < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("character index is negative", this));
}

for (i = 0; i < k && p < e; i++) {
final int c = StringSupport.preciseLength(enc, bytes.getUnsafeBytes(), p, e);

// If it's an invalid byte, just treat it as a single byte
if(! StringSupport.MBCLEN_CHARFOUND_P(c)) {
++p;
} else {
return count;
p += StringSupport.MBCLEN_CHARFOUND_LEN(c);
}
}

if (i < k) {
return nil();
} else {
return p;
}
}

@Specialization
@@ -723,24 +730,32 @@ public Object stringByteIndex(RubyString string, RubyString pattern, int offset)
int p = string.getByteList().getBegin();
final int e = p + string.getByteList().getRealSize();
int pp = pattern.getByteList().getBegin();
final int pe = pp + pattern.getByteList().getRealSize();
int s;
int ss;

final byte[] stringBytes = string.getByteList().getUnsafeBytes();
final byte[] patternBytes = pattern.getByteList().getUnsafeBytes();

// This is a slightly modified version of the loop as it appears in the Rubinius source. The code there
// did an extra memcmp for unknown reasons and that caused the pointer positions to shift. Removing them
// seemed to yield the same results while avoiding a potential ArrayIndexOutOfBounds exception. This
// removal may be misguided, so if there is a parity mismatch that's a good place to start looking.
for(s = p; p < e; s = ++p) {
for(s = p, ss = pp; p < e; s = ++p) {
if (stringBytes[p] != patternBytes[pp]) continue;

final int c = StringSupport.preciseLength(encoding, stringBytes, s, e);
while (p < e && pp < pe && stringBytes[p] == patternBytes[pp]) {
p++;
pp++;
}

if (StringSupport.MBCLEN_CHARFOUND_P(c)) {
return s;
if (pp < pe) {
p = s;
pp = ss;
} else {
return nil();
final int c = StringSupport.preciseLength(encoding, stringBytes, s, e);

if (StringSupport.MBCLEN_CHARFOUND_P(c)) {
return s;
} else {
return nil();
}
}
}