Skip to content

Commit

Permalink
[Truffle] Pass a lot more of String#byteslice.
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Mar 3, 2015
1 parent 626d862 commit 8e7db2f
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
6 changes: 0 additions & 6 deletions spec/truffle/tags/core/string/byteslice_tags.txt
@@ -1,9 +1,3 @@
fails:String#byteslice returns nil if index is outside of self
fails:String#byteslice calls to_int on the given index
fails:String#byteslice with index, length returns nil if the offset falls outside of self
fails:String#byteslice with index, length returns nil if the length is negative
fails:String#byteslice with index, length calls to_int on the given index and the given length
fails:String#byteslice with index, length returns subclass instances
fails:String#byteslice with index, length handles repeated application
fails:String#byteslice with Range returns subclass instances
fails:String#byteslice with Range calls to_int on range arguments
Expand Up @@ -53,22 +53,40 @@ public StringByteSubstringPrimitiveNode(StringByteSubstringPrimitiveNode prev) {

@Specialization
public Object stringByteSubstring(RubyString string, int index, UndefinedPlaceholder length) {
return stringByteSubstring(string, index, 1);
final Object subString = stringByteSubstring(string, index, 1);

if (subString == getContext().getCoreLibrary().getNilObject()) {
return subString;
}

if (((RubyString) subString).getByteList().length() == 0) {
return getContext().getCoreLibrary().getNilObject();
}

return subString;
}

@Specialization
public Object stringByteSubstring(RubyString string, int index, int length) {
final ByteList bytes = string.getBytes();

if (length < 0) {
return getContext().getCoreLibrary().getNilObject();
}

final int normalizedIndex = string.normalizeIndex(index);

if (normalizedIndex > bytes.length()) {
return getContext().getCoreLibrary().getNilObject();
}

int rangeEnd = normalizedIndex + length;
if (rangeEnd > bytes.getRealSize()) {
rangeEnd = bytes.getRealSize();
if (rangeEnd > bytes.length()) {
rangeEnd = bytes.length();
}

if (normalizedIndex < bytes.getBegin()) {
return getContext().getCoreLibrary().getNilObject();
}

final byte[] copiedBytes = Arrays.copyOfRange(bytes.getUnsafeBytes(), normalizedIndex, rangeEnd);
Expand All @@ -77,11 +95,36 @@ public Object stringByteSubstring(RubyString string, int index, int length) {
return taintResultNode.maybeTaint(string, result);
}

@Specialization
public Object stringByteSubstring(RubyString string, int index, double length) {
return stringByteSubstring(string, index, (int) length);
}

@Specialization
public Object stringByteSubstring(RubyString string, double index, UndefinedPlaceholder length) {
return stringByteSubstring(string, (int) index, 1);
}

@Specialization
public Object stringByteSubstring(RubyString string, double index, double length) {
return stringByteSubstring(string, (int) index, (int) length);
}

@Specialization
public Object stringByteSubstring(RubyString string, double index, int length) {
return stringByteSubstring(string, (int) index, length);
}

@Specialization
public Object stringByteSubstring(RubyString string, RubyRange range, UndefinedPlaceholder unused) {
return null;
}

@Specialization(guards = "!isRubyRange(arguments[1])")
public Object stringByteSubstring(RubyString string, Object indexOrRange, Object length) {
return null;
}

}

@RubiniusPrimitive(name = "string_check_null_safe", needsSelf = false)
Expand Down

0 comments on commit 8e7db2f

Please sign in to comment.