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

Commits on Mar 31, 2015

  1. Copy the full SHA
    fac2bf0 View commit details
  2. [Truffle] Fixed a bug with the 'string_copy_from' primitive.

    By not taking the full capacity into account, some limits were getting set wrong and as a result the bytes weren't being copied into the right location.  This manifested as a problem via Rubinius::Mirror::String#splice.
    nirvdrum committed Mar 31, 2015
    Copy the full SHA
    8bbedf1 View commit details
  3. Copy the full SHA
    fbbe3b5 View commit details
  4. Copy the full SHA
    016e4e1 View commit details
  5. Copy the full SHA
    36888b9 View commit details
53 changes: 11 additions & 42 deletions spec/truffle/tags/core/string/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,54 +1,23 @@
fails:String#[]= with Fixnum index taints self if other_str is tainted
fails:String#[]= with Fixnum index raises IndexError if the string index doesn't match a position in the string
fails:String#[]= with Fixnum index calls to_int on index
fails:String#[]= with Fixnum index calls #to_int to convert the index
fails:String#[]= with Fixnum index raises a TypeError if #to_int does not return an Fixnum
fails:String#[]= with Fixnum index raises an IndexError if #to_int returns a value out of range
fails:String#[]= with String index replaces fewer characters with more characters
fails:String#[]= with String index replaces more characters with fewer characters
fails:String#[]= with String index replaces characters with no characters
fails:String#[]= with String index raises an IndexError if the search String is not found
fails:String#[]= with String index replaces characters with a multibyte character
fails:String#[]= with String index replaces multibyte characters with characters
fails:String#[]= with String index replaces multibyte characters with multibyte characters
fails:String#[]= with String index encodes the String in an encoding compatible with the replacement
fails:String#[]= with String index raises an Encoding::CompatibilityError if the replacement encoding is incompatible
fails:String#[]= with a Regexp index replaces the matched text with the rhs
fails:String#[]= with a Regexp index raises IndexError if the regexp index doesn't match a position in the string
fails:String#[]= with a Regexp index calls #to_str to convert the replacement
fails:String#[]= with a Regexp index checks the match before calling #to_str to convert the replacement
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 a Regexp index encodes the String in an encoding compatible with the replacement
fails:String#[]= with a Regexp index raises an Encoding::CompatibilityError if the replacement encoding is incompatible
fails:String#[]= with a Regexp index with 3 arguments calls #to_int to convert the second object
fails:String#[]= with a Regexp index with 3 arguments raises a TypeError if #to_int does not return a Fixnum
fails:String#[]= with a Regexp index with 3 arguments uses the 2nd of 3 arguments as which capture should be replaced
fails:String#[]= with a Regexp index with 3 arguments allows the specified capture to be negative and count from the end
fails:String#[]= with a Regexp index with 3 arguments checks the match index before calling #to_str to convert the replacement
fails:String#[]= with a Regexp index with 3 arguments raises IndexError if the specified capture isn't available
fails:String#[]= with a Regexp index with 3 arguments when the optional capture does not match raises an IndexError before setting the replacement
fails:String#[]= with Fixnum index, count starts at idx and overwrites count characters before inserting the rest of other_str
fails:String#[]= with Fixnum index, count counts negative idx values from end of the string
fails:String#[]= with Fixnum index, count overwrites and deletes characters if count is more than the length of other_str
fails:String#[]= with Fixnum index, count deletes characters if other_str is an empty string
fails:String#[]= with Fixnum index, count deletes characters up to the maximum length of the existing string
fails:String#[]= with Fixnum index, count appends other_str to the end of the string if idx == the length of the string
fails:String#[]= with Fixnum index, count taints self if other_str is tainted
fails:String#[]= with Fixnum index, count calls #to_int to convert the index and count objects
fails:String#[]= with Fixnum index, count raises a TypeError if #to_int for index does not return an Integer
fails:String#[]= with Fixnum index, count raises a TypeError if #to_int for count does not return an Integer
fails:String#[]= with Fixnum index, count calls #to_str to convert the replacement object
fails:String#[]= with Fixnum index, count raises a TypeError of #to_str does not return a String
fails:String#[]= with Fixnum index, count raises an IndexError if |idx| is greater than the length of the string
fails:String#[]= with Fixnum index, count raises an IndexError if count < 0
fails:String#[]= with Fixnum index, count raises a TypeError if other_str is a type other than String
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 IndexError if the character index is out of range of a multibyte String
fails:String#[]= with Fixnum index, count encodes the String in an encoding compatible with the replacement
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
6 changes: 0 additions & 6 deletions spec/truffle/tags/core/string/prepend_tags.txt

This file was deleted.

22 changes: 0 additions & 22 deletions spec/truffle/tags/core/string/slice_tags.txt
Original file line number Diff line number Diff line change
@@ -1,24 +1,2 @@
fails:String#slice! with index calls to_int on index
fails:String#slice! with index returns the character given by the character index
fails:String#slice! with index, length deletes and returns the substring at idx and the given length
fails:String#slice! with index, length always taints resulting strings when self is tainted
fails:String#slice! with index, length calls to_int on idx and length
fails:String#slice! with index, length returns subclass instances
fails:String#slice! Range calls to_int on range arguments
fails:String#slice! Range works with Range subclasses
fails:String#slice! with Regexp deletes and returns the first match from self
fails:String#slice! with Regexp always taints resulting strings when self or regexp is tainted
fails:String#slice! with Regexp doesn't taint self when regexp is tainted
fails:String#slice! with Regexp returns subclass instances
fails:String#slice! with Regexp sets $~ to MatchData when there is a match and nil when there's none
fails:String#slice! with Regexp, index deletes and returns the capture for idx from self
fails:String#slice! with Regexp, index always taints resulting strings when self or regexp is tainted
fails:String#slice! with Regexp, index doesn't taint self when regexp is tainted
fails:String#slice! with Regexp, index calls to_int on idx
fails:String#slice! with Regexp, index returns subclass instances
fails:String#slice! with String removes and returns the first occurrence of other_str from self
fails:String#slice! with String taints resulting strings when other is tainted
fails:String#slice! with String doesn't set $~
fails:String#slice! with String returns a subclass instance when given a subclass instance
fails:String#slice! with Regexp, index accepts a Float for capture index
fails:String#slice! with Regexp, index calls #to_int to convert an Object to capture index
Original file line number Diff line number Diff line change
@@ -623,78 +623,6 @@ private StringPrimitiveNodes.StringSubstringPrimitiveNode getSubstringNode() {
}
}

@CoreMethod(names = "[]=", required = 2, lowerFixnumParameters = 0, raiseIfFrozenSelf = true)
public abstract static class ElementSetNode extends CoreMethodNode {

@Child private SizeNode sizeNode;
@Child private ToStrNode toStrNode;

public ElementSetNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
sizeNode = StringNodesFactory.SizeNodeFactory.create(context, sourceSection, new RubyNode[] { null });
toStrNode = ToStrNodeFactory.create(context, sourceSection, null);
}

public ElementSetNode(ElementSetNode prev) {
super(prev);
sizeNode = prev.sizeNode;
toStrNode = prev.toStrNode;
}

@Specialization
public RubyString elementSet(VirtualFrame frame, RubyString string, int index, Object replacement) {
final RubyString coerced = toStrNode.executeRubyString(frame, replacement);
StringNodesHelper.replaceInternal(string, StringNodesHelper.checkIndex(string, index, this), 1, coerced);

return coerced;
}

@Specialization
public RubyString elementSet(VirtualFrame frame, RubyString string, RubyRange.IntegerFixnumRange range, Object replacement) {
notDesignedForCompilation();

int begin = range.getBegin();
int end = range.getEnd();
final int stringLength = sizeNode.executeIntegerFixnum(frame, string);

if (begin < 0) {
begin += stringLength;

if (begin < 0) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().rangeError(range, this));
}

} else if (begin > stringLength) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(getContext().getCoreLibrary().rangeError(range, this));
}

if (end > stringLength) {
end = stringLength;
} else if (end < 0) {
end += stringLength;
}

if (! range.doesExcludeEnd()) {
end++;
}

int length = end - begin;

if (length < 0) {
length = 0;
}

final RubyString coerced = toStrNode.executeRubyString(frame, replacement);
StringNodesHelper.replaceInternal(string, StringNodesHelper.checkIndex(string, begin, this), length, coerced);

return coerced;
}
}

@CoreMethod(names = "=~", required = 1)
public abstract static class MatchOperatorNode extends CoreMethodNode {

@@ -1431,7 +1359,7 @@ public Object match(VirtualFrame frame, RubyString string, RubyRegexp regexp) {
}

@RubiniusOnly
@CoreMethod(names = "modify!")
@CoreMethod(names = "modify!", raiseIfFrozenSelf = true)
public abstract static class ModifyBangNode extends CoreMethodNode {

public ModifyBangNode(RubyContext context, SourceSection sourceSection) {
Original file line number Diff line number Diff line change
@@ -702,6 +702,50 @@ public Object stringByteIndex(RubyString string, int characters, int start) {
}
}

@Specialization
public Object stringByteIndex(RubyString string, RubyString pattern, int offset) {
// Taken from Rubinius's String::byte_index.

final int match_size = pattern.getByteList().length();

if (offset < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative start given", this));
}

if (match_size == 0) return offset;

if (string.scanForCodeRange() == StringSupport.CR_BROKEN) {
return nil();
}

final Encoding encoding = string.checkEncoding(pattern, this);
int p = string.getByteList().getBegin();
final int e = p + string.getByteList().getRealSize();
int pp = pattern.getByteList().getBegin();
int s;

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) {
if (stringBytes[p] != patternBytes[pp]) continue;

final int c = StringSupport.preciseLength(encoding, stringBytes, s, e);

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

return nil();
}
}

@RubiniusPrimitive(name = "string_previous_byte_index")
@@ -752,6 +796,8 @@ public StringCopyFromPrimitiveNode(StringCopyFromPrimitiveNode prev) {

@Specialization
public RubyString stringCopyFrom(RubyString string, RubyString other, int start, int size, int dest) {
// Taken from Rubinius's String::copy_from.

int src = start;
int dst = dest;
int cnt = size;
@@ -762,7 +808,10 @@ public RubyString stringCopyFrom(RubyString string, RubyString other, int start,
if(src < 0) src = 0;
if(cnt > osz - src) cnt = osz - src;

int sz = string.getByteList().length();
// This bounds checks on the total capacity rather than the virtual
// size() of the String. This allows for string adjustment within
// the capacity without having to change the virtual size first.
int sz = string.getByteList().getUnsafeBytes().length;
if(dst >= sz) return string;
if(dst < 0) dst = 0;
if(cnt > sz - dst) cnt = sz - dst;