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

Commits on Mar 20, 2015

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    bba8243 View commit details
  2. Copy the full SHA
    d663235 View commit details
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/string/reverse_tags.txt

This file was deleted.

90 changes: 61 additions & 29 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Original file line number Diff line number Diff line change
@@ -1340,7 +1340,9 @@ public Object initializeCopy(RubyString self, RubyString from) {
return self;
}

self.getBytes().replace(from.getBytes().bytes());
self.getByteList().replace(from.getByteList().bytes());
self.getByteList().setEncoding(from.getByteList().getEncoding());
self.setCodeRange(from.getCodeRange());

return self;
}
@@ -1998,43 +2000,81 @@ public RubySymbol toSym(RubyString string) {
}
}

@CoreMethod(names = "reverse", taintFromSelf = true)
public abstract static class ReverseNode extends CoreMethodNode {
@CoreMethod(names = "reverse!", raiseIfFrozenSelf = true)
@ImportGuards(StringGuards.class)
public abstract static class ReverseBangNode extends CoreMethodNode {

public ReverseNode(RubyContext context, SourceSection sourceSection) {
public ReverseBangNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public ReverseNode(ReverseNode prev) {
public ReverseBangNode(ReverseBangNode prev) {
super(prev);
}

@Specialization
public RubyString reverse(RubyString string) {
notDesignedForCompilation();

return RubyString.fromByteList(string.getLogicalClass(), StringNodesHelper.reverse(string));
@Specialization(guards = "reverseIsEqualToSelf")
public RubyString reverseNoOp(RubyString string) {
return string;
}
}

@CoreMethod(names = "reverse!", raiseIfFrozenSelf = true)
public abstract static class ReverseBangNode extends CoreMethodNode {
@Specialization(guards = { "!reverseIsEqualToSelf", "isSingleByteOptimizable" })
public RubyString reverseSingleByteOptimizable(RubyString string) {
// Taken from org.jruby.RubyString#reverse!

public ReverseBangNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
string.modify();

public ReverseBangNode(ReverseBangNode prev) {
super(prev);
final byte[] bytes = string.getByteList().getUnsafeBytes();
final int p = string.getByteList().getBegin();
final int len = string.getByteList().getRealSize();

for (int i = 0; i < len >> 1; i++) {
byte b = bytes[p + i];
bytes[p + i] = bytes[p + len - i - 1];
bytes[p + len - i - 1] = b;
}

return string;
}

@Specialization
@Specialization(guards = { "!reverseIsEqualToSelf", "!isSingleByteOptimizable" })
public RubyString reverse(RubyString string) {
notDesignedForCompilation();
// Taken from org.jruby.RubyString#reverse!

string.modify();

final byte[] bytes = string.getByteList().getUnsafeBytes();
int p = string.getByteList().getBegin();
final int len = string.getByteList().getRealSize();

final Encoding enc = string.getByteList().getEncoding();
final int end = p + len;
int op = len;
final byte[] obytes = new byte[len];
boolean single = true;

while (p < end) {
int cl = StringSupport.length(enc, bytes, p, end);
if (cl > 1 || (bytes[p] & 0x80) != 0) {
single = false;
op -= cl;
System.arraycopy(bytes, p, obytes, op, cl);
p += cl;
} else {
obytes[--op] = bytes[p++];
}
}

string.getByteList().setUnsafeBytes(obytes);
if (string.getCodeRange() == StringSupport.CR_UNKNOWN) {
string.setCodeRange(single ? StringSupport.CR_7BIT : StringSupport.CR_VALID);
}

string.set(StringNodesHelper.reverse(string));
return string;
}

public static boolean reverseIsEqualToSelf(RubyString string) {
return string.getByteList().getRealSize() <= 1;
}
}

@CoreMethod(names = "unpack", required = 1)
@@ -2265,14 +2305,6 @@ public static ByteList chompWithString(RubyString string, RubyString stringToCho
return byteList;
}

@TruffleBoundary
public static ByteList reverse(RubyString string) {
ByteList byteListString = ByteList.create(new StringBuilder(string.toString()).reverse().toString());
byteListString.setEncoding(string.getBytes().getEncoding());

return byteListString;
}

@TruffleBoundary
public static ByteList swapcase(RubyString string) {
char[] charArray = string.toString().toCharArray();
4 changes: 4 additions & 0 deletions truffle/src/main/ruby/core/rubinius/common/string.rb
Original file line number Diff line number Diff line change
@@ -52,6 +52,10 @@ def hex
to_inum(16, false)
end

def reverse
dup.reverse!
end

def split(pattern=nil, limit=undefined)
Rubinius::Splitter.split(self, pattern, limit)
end