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

Commits on Oct 15, 2015

  1. Copy the full SHA
    87d73d3 View commit details
  2. Copy the full SHA
    26fb9e4 View commit details
Showing with 31 additions and 12 deletions.
  1. +31 −12 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/StringPrimitiveNodes.java
Original file line number Diff line number Diff line change
@@ -1017,8 +1017,12 @@ public StringCopyFromPrimitiveNode(RubyContext context, SourceSection sourceSect
super(context, sourceSection);
}

@Specialization(guards = "isRubyString(other)")
public DynamicObject stringCopyFrom(DynamicObject string, DynamicObject other, int start, int size, int dest) {
@Specialization(guards = { "isRubyString(other)", "size >= 0", "!offsetTooLarge(start, other)", "!offsetTooLargeRaw(dest, string)" })
public DynamicObject stringCopyFrom(DynamicObject string, DynamicObject other, int start, int size, int dest,
@Cached("createBinaryProfile()") ConditionProfile negativeStartOffsetProfile,
@Cached("createBinaryProfile()") ConditionProfile sizeTooLargeInReplacementProfile,
@Cached("createBinaryProfile()") ConditionProfile negativeDestinationOffsetProfile,
@Cached("createBinaryProfile()") ConditionProfile sizeTooLargeInStringProfile) {
// Taken from Rubinius's String::copy_from.

int src = start;
@@ -1027,25 +1031,40 @@ public DynamicObject stringCopyFrom(DynamicObject string, DynamicObject other, i

final ByteList otherBytes = StringOperations.getByteList(other);
int osz = otherBytes.length();
if(src >= osz) return string;
if(cnt < 0) return string;
if(src < 0) src = 0;
if(cnt > osz - src) cnt = osz - src;
if(negativeStartOffsetProfile.profile(src < 0)) src = 0;
if(sizeTooLargeInReplacementProfile.profile(cnt > osz - src)) cnt = osz - src;

// 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.
final ByteList stringBytes = StringOperations.getByteList(string);
int sz = stringBytes.unsafeBytes().length - stringBytes.begin();
if(dst >= sz) return string;
if(dst < 0) dst = 0;
if(cnt > sz - dst) cnt = sz - dst;
if(negativeDestinationOffsetProfile.profile(dst < 0)) dst = 0;
if(sizeTooLargeInStringProfile.profile(cnt > sz - dst)) cnt = sz - dst;

System.arraycopy(otherBytes.unsafeBytes(), otherBytes.begin() + src, stringBytes.getUnsafeBytes(), stringBytes.begin() + dest, cnt);

return string;
}

@Specialization(guards = { "isRubyString(other)", "size < 0 || (offsetTooLarge(start, other) || offsetTooLargeRaw(dest, string))" })
public DynamicObject stringCopyFromWithNegativeSize(DynamicObject string, DynamicObject other, int start, int size, int dest) {
return string;
}

protected boolean offsetTooLarge(int offset, DynamicObject string) {
assert RubyGuards.isRubyString(string);

return offset >= StringOperations.getByteList(string).realSize();
}

protected boolean offsetTooLargeRaw(int offset, DynamicObject string) {
assert RubyGuards.isRubyString(string);

// 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.
final ByteList byteList = StringOperations.getByteList(string);
return offset >= (byteList.unsafeBytes().length - byteList.begin());
}

}

@RubiniusPrimitive(name = "string_resize_capacity", needsSelf = false, lowerFixnumParameters = 1)