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

Commits on Apr 13, 2016

  1. Copy the full SHA
    1e0cc68 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a52432e View commit details
Showing with 8 additions and 12 deletions.
  1. +8 −12 truffle/src/main/java/org/jruby/truffle/core/rubinius/StringPrimitiveNodes.java
Original file line number Diff line number Diff line change
@@ -1453,6 +1453,7 @@ protected boolean patternFitsEvenly(DynamicObject string, int size) {
}

@RubiniusPrimitive(name = "string_splice", needsSelf = false, lowerFixnumParameters = {2, 3})
@ImportStatic(StringGuards.class)
public static abstract class StringSplicePrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child private RopeNodes.MakeConcatNode appendMakeConcatNode;
@@ -1542,7 +1543,7 @@ public DynamicObject splice(DynamicObject string, DynamicObject other, int splic
return string;
}

@Specialization(guards = { "!indexAtEitherBounds(string, spliceByteIndex)", "isRubyString(other)", "isRubyEncoding(rubyEncoding)", "isRopeBuffer(string)" })
@Specialization(guards = { "!indexAtEitherBounds(string, spliceByteIndex)", "isRubyString(other)", "isRubyEncoding(rubyEncoding)", "isRopeBuffer(string)", "isSingleByteOptimizable(string)" })
public DynamicObject spliceBuffer(DynamicObject string, DynamicObject other, int spliceByteIndex, int byteCountToReplace, DynamicObject rubyEncoding,
@Cached("createBinaryProfile()") ConditionProfile sameCodeRangeProfile,
@Cached("createBinaryProfile()") ConditionProfile brokenCodeRangeProfile) {
@@ -1554,17 +1555,10 @@ public DynamicObject spliceBuffer(DynamicObject string, DynamicObject other, int
final ByteList byteList = new ByteList(source.byteLength() + insert.byteLength() - byteCountToReplace);

byteList.append(source.getByteList(), 0, spliceByteIndex);

for (int i = 0; i < insert.byteLength(); i++) {
byteList.append(insert.getBytes()[i]);
}

byteList.append(insert.getBytes());
byteList.append(source.getByteList(), rightSideStartingIndex, source.byteLength() - rightSideStartingIndex);
byteList.setEncoding(encoding);

// NB: The character count is only accurate for single byte-optimizable strings. Rope buffers are not supported
// in general use. If we want to allow for wide characters we would need to recalculate the length doing a
// full scan.
final Rope buffer = new RopeBuffer(byteList,
RopeNodes.MakeConcatNode.commonCodeRange(source.getCodeRange(), insert.getCodeRange(), sameCodeRangeProfile, brokenCodeRangeProfile),
source.isSingleByteOptimizable() && insert.isSingleByteOptimizable(),
@@ -1838,6 +1832,11 @@ private DynamicObject makeRope(DynamicObject string, int beg, int len) {
private DynamicObject makeBuffer(DynamicObject string, int beg, int len) {
assert RubyGuards.isRubyString(string);

if (!StringGuards.isSingleByteOptimizable(string)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().internalError("Taking the substring of MBC rope buffer is not currently supported", this));
}

final RopeBuffer buffer = (RopeBuffer) rope(string);

if (allocateNode == null) {
@@ -1850,9 +1849,6 @@ private DynamicObject makeBuffer(DynamicObject string, int beg, int len) {
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection()));
}

// NB: This is only valid for the single-byte case. If multi-byte, the code range must be recalculated.
// This is not intended to be a 100% correct implementation, since you should normally be using the
// immutable rope variant.
final DynamicObject ret = allocateNode.allocate(
Layouts.BASIC_OBJECT.getLogicalClass(string),
new RopeBuffer(new ByteList(buffer.getByteList(), beg, len), buffer.getCodeRange(), buffer.isSingleByteOptimizable(), len),