-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Implemented the
string_substring
primitive for rope buffers.
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
Showing
1 changed file
with
35 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,7 @@ | |
import org.jruby.truffle.core.rope.CodeRange; | ||
import org.jruby.truffle.core.rope.RepeatingRope; | ||
import org.jruby.truffle.core.rope.Rope; | ||
import org.jruby.truffle.core.rope.RopeBuffer; | ||
import org.jruby.truffle.core.rope.RopeConstants; | ||
import org.jruby.truffle.core.rope.RopeNodes; | ||
import org.jruby.truffle.core.rope.RopeNodesFactory; | ||
|
@@ -1655,7 +1656,8 @@ public Object stringSubstring(DynamicObject string, int beg, int len, | |
@Cached("createBinaryProfile()") ConditionProfile negativeBeginProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile stillNegativeBeginProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile tooLargeTotalProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile negativeLengthProfile) { | ||
@Cached("createBinaryProfile()") ConditionProfile negativeLengthProfile, | ||
@Cached("createBinaryProfile()") ConditionProfile mutableRopeProfile) { | ||
// Taken from org.jruby.RubyString#substr19. | ||
final Rope rope = rope(string); | ||
if (emptyStringProfile.profile(rope.isEmpty())) { | ||
|
@@ -1684,6 +1686,10 @@ public Object stringSubstring(DynamicObject string, int beg, int len, | |
beg = 0; | ||
} | ||
|
||
if (mutableRopeProfile.profile(rope instanceof RopeBuffer)) { | ||
return makeBuffer(string, beg, len); | ||
} | ||
|
||
return makeRope(string, beg, len); | ||
} | ||
|
||
|
@@ -1790,6 +1796,34 @@ private DynamicObject makeRope(DynamicObject string, int beg, int len) { | |
return ret; | ||
} | ||
|
||
private DynamicObject makeBuffer(DynamicObject string, int beg, int len) { | ||
assert RubyGuards.isRubyString(string); | ||
|
||
final RopeBuffer buffer = (RopeBuffer) rope(string); | ||
|
||
if (allocateNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
allocateNode = insert(AllocateObjectNodeGen.create(getContext(), getSourceSection(), null, null)); | ||
} | ||
|
||
if (taintResultNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
taintResultNode = insert(new TaintResultNode(getContext(), getSourceSection())); | ||
} | ||
|
||
// NB: This is only valid for the single-byte case. If multi-byte, the code range must be recalculated. | ||
// This is not intended to be a 100% correct implementation, since you should normally be using the | ||
// immutable rope variant. | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
nirvdrum
Author
Contributor
|
||
final DynamicObject ret = allocateNode.allocate( | ||
Layouts.BASIC_OBJECT.getLogicalClass(string), | ||
new RopeBuffer(new ByteList(buffer.getByteList(), beg, len), buffer.getCodeRange(), buffer.isSingleByteOptimizable(), len), | ||
null); | ||
|
||
taintResultNode.maybeTaint(string, ret); | ||
|
||
return ret; | ||
} | ||
|
||
} | ||
|
||
@RubiniusPrimitive(name = "string_from_bytearray", needsSelf = false, lowerFixnumParameters = { 1, 2 }) | ||
|
Maybe an
assert
then? Or computing it if len != 1?