Skip to content

Commit

Permalink
[Truffle] Fixed another case in String#slice.
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Mar 22, 2015
1 parent 09bfd43 commit 2614e49
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 20 deletions.
1 change: 0 additions & 1 deletion spec/truffle/tags/core/string/slice_tags.txt
Expand Up @@ -11,7 +11,6 @@ fails:String#slice! with index, length deletes and returns the substring at idx
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! with index, length returns the substring given by the character offsets
fails:String#slice! Range calls to_int on range arguments
fails:String#slice! Range works with Range subclasses
fails:String#slice! Range returns the substring given by the character offsets of the range
Expand Down
32 changes: 13 additions & 19 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
Expand Up @@ -465,6 +465,7 @@ public abstract static class GetIndexNode extends CoreMethodNode {
@Child private CallDispatchHeadNode includeNode;
@Child private CallDispatchHeadNode matchNode;
@Child private KernelNodes.DupNode dupNode;
@Child private StringPrimitiveNodes.StringSubstringPrimitiveNode substringNode;

private final BranchProfile outOfBounds = BranchProfile.create();

Expand Down Expand Up @@ -523,22 +524,15 @@ public Object slice(RubyString string, RubyRange.IntegerFixnumRange range, @Supp
}

@Specialization
public Object slice(RubyString string, int start, int length) {
// TODO(CS): not sure if this is right - encoding
final ByteList bytes = string.getBytes();
final int begin = string.normalizeIndex(start);

if (begin < 0 || begin > bytes.length() || length < 0) {
outOfBounds.enter();
return nil();
} else {
final int end = Math.min(bytes.length(), begin + length);

final ByteList byteList = new ByteList(bytes, begin, end - begin);
byteList.setEncoding(string.getByteList().getEncoding());
public Object slice(VirtualFrame frame, RubyString string, int start, int length) {
if (substringNode == null) {
CompilerDirectives.transferToInterpreter();

return getContext().makeString(string.getLogicalClass(), byteList);
substringNode = insert(StringPrimitiveNodesFactory.StringSubstringPrimitiveNodeFactory.create(
getContext(), getSourceSection(), new RubyNode[] { null, null, null }));
}

return substringNode.executeRubyString(frame, string, start, length);
}

@Specialization(guards = "!isUndefinedPlaceholder(arguments[2])")
Expand All @@ -550,7 +544,7 @@ public Object slice(VirtualFrame frame, RubyString string, int start, Object len
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}

return slice(string, start, toIntNode.executeIntegerFixnum(frame, length));
return slice(frame, string, start, toIntNode.executeIntegerFixnum(frame, length));
}

@Specialization(guards = { "!isRubyRange(arguments[1])", "!isRubyRegexp(arguments[1])", "!isRubyString(arguments[1])", "!isUndefinedPlaceholder(arguments[2])" })
Expand All @@ -562,7 +556,7 @@ public Object slice(VirtualFrame frame, RubyString string, Object start, Object
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}

return slice(string, toIntNode.executeIntegerFixnum(frame, start), toIntNode.executeIntegerFixnum(frame, length));
return slice(frame, string, toIntNode.executeIntegerFixnum(frame, start), toIntNode.executeIntegerFixnum(frame, length));
}

@Specialization
Expand Down Expand Up @@ -1442,7 +1436,7 @@ public InsertNode(InsertNode prev) {
}

@Specialization
public RubyString insert(RubyString string, int index, RubyString otherString) {
public RubyString insert(VirtualFrame frame, RubyString string, int index, RubyString otherString) {
notDesignedForCompilation();

if (index == -1) {
Expand Down Expand Up @@ -1470,8 +1464,8 @@ public RubyString insert(RubyString string, int index, RubyString otherString) {
}

// TODO (Kevin): using node directly and cast
RubyString firstPart = (RubyString) getIndexNode.slice(string, 0, index);
RubyString secondPart = (RubyString) getIndexNode.slice(string, index, string.length());
RubyString firstPart = (RubyString) getIndexNode.slice(frame, string, 0, index);
RubyString secondPart = (RubyString) getIndexNode.slice(frame, string, index, string.length());

RubyString concatenated = concatNode.concat(concatNode.concat(firstPart, otherString), secondPart);

Expand Down
Expand Up @@ -56,6 +56,7 @@
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.ImportGuards;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.Encoding;
Expand Down Expand Up @@ -864,8 +865,11 @@ public StringSubstringPrimitiveNode(RubyContext context, SourceSection sourceSec

public StringSubstringPrimitiveNode(StringSubstringPrimitiveNode prev) {
super(prev);
taintResultNode = prev.taintResultNode;
}

public abstract RubyString executeRubyString(VirtualFrame frame, RubyString string, int beg, int len);

@Specialization(guards = "isSingleByteOptimizable")
public Object stringSubstringSingleByteOptimizable(RubyString string, int beg, int len) {
// Taken from org.jruby.RubyString#substr19.
Expand Down

0 comments on commit 2614e49

Please sign in to comment.