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

Commits on Jun 9, 2015

  1. Copy the full SHA
    b2dea44 View commit details
  2. [Truffle] Fixed the 'string_index' primitive.

    Since we weren't converting from byte index to character index, we were using the offset for the index operation on multibyte characters.
    nirvdrum committed Jun 9, 2015
    Copy the full SHA
    1ff088c View commit details
  3. Copy the full SHA
    6e3e1b6 View commit details
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/rindex_tags.txt
Original file line number Diff line number Diff line change
@@ -5,5 +5,4 @@ fails(regexp):String#rindex with Regexp starts the search at the given offset
fails(regexp):String#rindex with Regexp supports \G which matches at the given start offset
fails(regexp):String#rindex with Regexp tries to convert start_offset to an integer via to_int
fails(regexp):String#rindex with Regexp returns the reverse character index of a multibyte character
fails(regexp):String#rindex with Regexp returns the character index before the finish
fails:String#rindex with Regexp returns nil if the substring isn't found
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/split_tags.txt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -25,8 +25,9 @@ public static boolean isAsciiCompatible(RubyString string) {
return StringNodes.getByteList(string).getEncoding().isAsciiCompatible();
}

public static boolean isSingleByteOptimizableOrAsciiCompatible(RubyString string) {
return isSingleByteOptimizable(string) || isAsciiCompatible(string);
public static boolean isSingleByteOptimizableOrAsciiOnly(RubyString string) {
// TODO (nirvdrnum 08-Jun-15) Rubinius tracks whether a String is ASCII-only via a field in the String.
return isSingleByteOptimizable(string);
}

public static boolean isSingleByte(RubyString string) {
Original file line number Diff line number Diff line change
@@ -602,16 +602,26 @@ public Object stringToF(RubyString string) {
@RubiniusPrimitive(name = "string_index", lowerFixnumParameters = 1)
public static abstract class StringIndexPrimitiveNode extends RubiniusPrimitiveNode {

@Child StringByteCharacterIndexNode byteIndexToCharIndexNode;

public StringIndexPrimitiveNode(RubyContext context, SourceSection sourceSection) {

super(context, sourceSection);
}

@Specialization
public Object stringIndex(RubyString string, RubyString pattern, int start) {
public Object stringIndex(VirtualFrame frame, RubyString string, RubyString pattern, int start) {
if (byteIndexToCharIndexNode == null) {
CompilerDirectives.transferToInterpreter();
byteIndexToCharIndexNode = insert(StringPrimitiveNodesFactory.StringByteCharacterIndexNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{}));
}

// Rubinius will pass in a byte index for the `start` value, but StringSupport.index requires a character index.
final int charIndex = byteIndexToCharIndexNode.executeStringBytCharacterIndex(frame, string, start, 0);

final int index = StringSupport.index(StringNodes.getCodeRangeable(string),
StringNodes.getCodeRangeable(pattern),
start, StringNodes.getByteList(string).getEncoding());
charIndex, StringNodes.getByteList(string).getEncoding());

if (index == -1) {
return nil();
@@ -652,19 +662,21 @@ public StringByteCharacterIndexNode(RubyContext context, SourceSection sourceSec
super(context, sourceSection);
}

@Specialization(guards = "isSingleByteOptimizableOrAsciiCompatible(string)")
public abstract int executeStringBytCharacterIndex(VirtualFrame frame, RubyString string, int index, int start);

@Specialization(guards = "isSingleByteOptimizableOrAsciiOnly(string)")
public int stringByteCharacterIndexSingleByte(RubyString string, int index, int start) {
// Taken from Rubinius's String::find_byte_character_index.
return index;
}

@Specialization(guards = { "!isSingleByteOptimizableOrAsciiCompatible(string)", "isFixedWidthEncoding(string)", "!isValidUtf8(string)" })
@Specialization(guards = { "!isSingleByteOptimizableOrAsciiOnly(string)", "isFixedWidthEncoding(string)", "!isValidUtf8(string)" })
public int stringByteCharacterIndexFixedWidth(RubyString string, int index, int start) {
// Taken from Rubinius's String::find_byte_character_index.
return index / StringNodes.getByteList(string).getEncoding().minLength();
}

@Specialization(guards = { "!isSingleByteOptimizableOrAsciiCompatible(string)", "!isFixedWidthEncoding(string)", "isValidUtf8(string)" })
@Specialization(guards = { "!isSingleByteOptimizableOrAsciiOnly(string)", "!isFixedWidthEncoding(string)", "isValidUtf8(string)" })
public int stringByteCharacterIndexValidUtf8(RubyString string, int index, int start) {
// Taken from Rubinius's String::find_byte_character_index.

@@ -673,7 +685,7 @@ public int stringByteCharacterIndexValidUtf8(RubyString string, int index, int s
}

@TruffleBoundary
@Specialization(guards = { "!isSingleByteOptimizableOrAsciiCompatible(string)", "!isFixedWidthEncoding(string)", "!isValidUtf8(string)" })
@Specialization(guards = { "!isSingleByteOptimizableOrAsciiOnly(string)", "!isFixedWidthEncoding(string)", "!isValidUtf8(string)" })
public int stringByteCharacterIndex(RubyString string, int index, int start) {
// Taken from Rubinius's String::find_byte_character_index and Encoding::find_byte_character_index.