Skip to content

Commit

Permalink
[Truffle] Implemented String#[](String).
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Mar 2, 2015
1 parent b27513d commit ebd6f90
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/string/slice_tags.txt
Expand Up @@ -14,11 +14,7 @@ fails:String#slice with Regexp, index returns nil if there is no capture for the
fails:String#slice with Regexp, index returns subclass instances
fails:String#slice with Regexp, group always taints resulting strings when self or regexp is tainted
fails:String#slice with Regexp, group returns subclass instances
fails:String#slice with String returns other_str if it occurs in self
fails:String#slice with String taints resulting strings when other is tainted
fails:String#slice with String doesn't set $~
fails:String#slice with String returns nil if there is no match
fails:String#slice with String returns a subclass instance when given a subclass instance
fails:String#slice! with index calls to_int on index
fails:String#slice! with index returns the character given by the character index
fails:String#slice! with index, length deletes and returns the substring at idx and the given length
Expand Down Expand Up @@ -46,7 +42,6 @@ fails:String#slice! with Regexp, index returns subclass instances
fails:String#slice! with String removes and returns the first occurrence of other_str from self
fails:String#slice! with String taints resulting strings when other is tainted
fails:String#slice! with String doesn't set $~
fails:String#slice! with String returns nil if self does not contain other
fails:String#slice! with String returns a subclass instance when given a subclass instance
fails:String#slice! with Regexp, index accepts a Float for capture index
fails:String#slice! with Regexp, index calls #to_int to convert an Object to capture index
Expand Up @@ -285,6 +285,8 @@ public abstract static class GetIndexNode extends CoreMethodNode {

@Child private ToIntNode toIntNode;
@Child private MatchDataNodes.GetIndexNode getMatchDataIndexNode;
@Child private CallDispatchHeadNode includeNode;
@Child private KernelNodes.DupNode dupNode;

private final BranchProfile outOfBounds = BranchProfile.create();

Expand Down Expand Up @@ -454,6 +456,29 @@ public Object slice(VirtualFrame frame, RubyString string, RubyRegexp regexp, Ob

return getMatchDataIndexNode.getIndex((RubyMatchData) matchData, index);
}

@Specialization
public Object slice(VirtualFrame frame, RubyString string, RubyString matchStr, @SuppressWarnings("unused") UndefinedPlaceholder undefined) {
notDesignedForCompilation();

if (includeNode == null) {
CompilerDirectives.transferToInterpreter();
includeNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext()));
}

Boolean result = (Boolean) includeNode.call(frame, string, "include?", null, matchStr);

This comment has been minimized.

Copy link
@eregon

eregon Mar 3, 2015

Member

Let's not box when we can avoid it ;)

This comment has been minimized.

Copy link
@nirvdrum

nirvdrum Mar 3, 2015

Author Contributor

Ahh, I completely forgot callBoolean existed. Thanks.

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Mar 3, 2015

Contributor

I think @eregon meant the type of the local variable anyway.

This comment has been minimized.

Copy link
@eregon

eregon Mar 3, 2015

Member

Yeah I meant the local Boolean which is likely an anti-pattern, but indeed the true solution seems callBoolean here.


if (result) {
if (dupNode == null) {
CompilerDirectives.transferToInterpreter();
dupNode = insert(KernelNodesFactory.DupNodeFactory.create(getContext(), getSourceSection(), new RubyNode[]{}));
}

return dupNode.dup(frame, matchStr);
}

return getContext().getCoreLibrary().getNilObject();
}
}

@CoreMethod(names = "[]=", required = 2, lowerFixnumParameters = 0)
Expand Down

0 comments on commit ebd6f90

Please sign in to comment.