Skip to content

Commit

Permalink
[Truffle] Completed String#*.
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Mar 16, 2015
1 parent 83a8b2e commit 76b7f0c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
5 changes: 0 additions & 5 deletions spec/truffle/tags/core/string/multiply_tags.txt

This file was deleted.

Expand Up @@ -35,6 +35,7 @@
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.BranchProfile;

import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jcodings.Encoding;
import org.jcodings.specific.ASCIIEncoding;
import org.jcodings.specific.UTF8Encoding;
Expand Down Expand Up @@ -97,21 +98,31 @@ public RubyString add(RubyString a, RubyString b) {
}
}

@CoreMethod(names = "*", required = 1, lowerFixnumParameters = 0)
@CoreMethod(names = "*", required = 1, lowerFixnumParameters = 0, taintFromSelf = true)
public abstract static class MulNode extends CoreMethodNode {

private final ConditionProfile negativeTimesProfile = ConditionProfile.createBinaryProfile();

@Child private ToIntNode toIntNode;

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

public MulNode(MulNode prev) {
super(prev);
toIntNode = prev.toIntNode;
}

@Specialization
public RubyString add(RubyString string, int times) {
public RubyString multiply(RubyString string, int times) {
notDesignedForCompilation();

if (negativeTimesProfile.profile(times < 0)) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(getContext().getCoreLibrary().argumentError("negative argument", this));
}

final ByteList inputBytes = string.getBytes();
final ByteList outputBytes = new ByteList(string.getBytes().length() * times);

Expand All @@ -121,7 +132,25 @@ public RubyString add(RubyString string, int times) {

outputBytes.setEncoding(inputBytes.getEncoding());

return new RubyString(getContext().getCoreLibrary().getStringClass(), outputBytes);
return getContext().makeString(string.getLogicalClass(), outputBytes);
}

@Specialization
public RubyString multiply(RubyString string, RubyBignum times) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().rangeError("bignum too big to convert into `long'", this));
}

@Specialization(guards = { "!isRubyBignum(arguments[1])", "!isInteger(arguments[1])" })
public RubyString multiply(VirtualFrame frame, RubyString string, Object times) {
if (toIntNode == null) {
CompilerDirectives.transferToInterpreter();
toIntNode = insert(ToIntNodeFactory.create(getContext(), getSourceSection(), null));
}

return multiply(string, toIntNode.executeIntegerFixnum(frame, times));
}
}

Expand Down

0 comments on commit 76b7f0c

Please sign in to comment.