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

Commits on Mar 31, 2015

  1. Copy the full SHA
    9f259cb View commit details
  2. Copy the full SHA
    de0b131 View commit details
15 changes: 0 additions & 15 deletions spec/truffle/tags/core/string/index_tags.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
fails:String#index calls #to_str to convert the first argument
fails:String#index calls #to_int to convert the second argument
fails:String#index with String behaves the same as String#index(char) for one-character strings
fails:String#index with String returns the index of the first occurrence of the given substring
fails:String#index with String doesn't set $~
fails:String#index with String ignores string subclasses
fails:String#index with String starts the search at the given offset
fails:String#index with String starts the search at offset + self.length if offset is negative
fails:String#index with String returns nil if the substring isn't found
fails:String#index with String returns the character index of a multibyte character
fails:String#index with String returns the character index after offset
fails:String#index with String returns the character index after a partial first match
fails:String#index with Regexp behaves the same as String#index(string) for escaped string regexps
fails:String#index with Regexp starts the search at offset + self.length if offset is negative
fails:String#index with Regexp supports \G which matches at the given start offset
fails:String#index with Regexp returns the character index of a multibyte character
fails:String#index with Regexp returns the character index after offset
fails:String#index with Regexp treats the offset as a character index
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/string/partition_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -657,8 +657,95 @@ public StringCharacterIndexPrimitiveNode(StringCharacterIndexPrimitiveNode prev)
}

@Specialization
public Object stringCharacterIndex(RubyString string, Object indexedString, Object start) {
throw new UnsupportedOperationException("string_character_index");
public Object stringCharacterIndex(RubyString string, RubyString pattern, int offset) {
notDesignedForCompilation();

if (offset < 0) {
return nil();
}

final int total = string.getByteList().length();
int p = string.getByteList().getBegin();
final int e = p + total;
int pp = pattern.getByteList().getBegin();
final int pe = pp + pattern.getByteList().length();
int s;
int ss;

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

if (StringSupport.isSingleByteOptimizable(string, string.getByteList().getEncoding())) {
for(s = p += offset, ss = pp; p < e; s = ++p) {
if (stringBytes[p] != patternBytes[pp]) continue;

while (p < e && pp < pe && stringBytes[p] == patternBytes[pp]) {
p++;
pp++;
}

if (pp < pe) {
p = s;
pp = ss;
} else {
return s;
}
}

return nil();
}

final Encoding enc = string.getByteList().getEncoding();
int index = 0;
int c;

while(p < e && index < offset) {
c = StringSupport.preciseLength(enc, stringBytes, p, e);

if (StringSupport.MBCLEN_CHARFOUND_P(c)) {
p += c;
index++;
} else {
return nil();
}
}

for(s = p, ss = pp; p < e; s = p += c, ++index) {
c = StringSupport.preciseLength(enc, stringBytes, p, e);
if ( !StringSupport.MBCLEN_CHARFOUND_P(c)) return nil();

if (stringBytes[p] != patternBytes[pp]) continue;

while (p < e && pp < pe) {
boolean breakOut = false;

for (int pc = p + c; p < e && p < pc && pp < pe; ) {
if (stringBytes[p] == patternBytes[pp]) {
++p;
++pp;
} else {
breakOut = true;
break;
}
}

if (breakOut) {
break;
}

c = StringSupport.preciseLength(enc, stringBytes, p, e);
if (! StringSupport.MBCLEN_CHARFOUND_P(c)) break;
}

if (pp < pe) {
p = s;
pp = ss;
} else {
return index;
}
}

return nil();
}

}