|
131 | 131 | public class CExtNodes {
|
132 | 132 |
|
133 | 133 | public static Pointer newNativeStringPointer(int capacity, RubyLanguage language) {
|
134 |
| - return Pointer.mallocAutoRelease(capacity + 1, language); |
| 134 | + // We need up to 4 \0 bytes for UTF-32. Always use 4 for speed rather than checking the encoding min length. |
| 135 | + Pointer pointer = Pointer.mallocAutoRelease(capacity + 4, language); |
| 136 | + pointer.writeInt(capacity, 0); |
| 137 | + return pointer; |
135 | 138 | }
|
136 | 139 |
|
137 | 140 | private static long getNativeStringCapacity(Pointer pointer) {
|
@@ -732,13 +735,24 @@ public abstract static class RbStrSetLenNode extends CoreMethodArrayArgumentsNod
|
732 | 735 | protected RubyString strSetLen(RubyString string, int newByteLength,
|
733 | 736 | @Cached RubyStringLibrary libString,
|
734 | 737 | @Cached StringToNativeNode stringToNativeNode,
|
735 |
| - @Cached MutableTruffleString.FromNativePointerNode fromNativePointerNode) { |
| 738 | + @Cached MutableTruffleString.FromNativePointerNode fromNativePointerNode, |
| 739 | + @Cached ConditionProfile minLengthOneProfile) { |
736 | 740 | var pointer = stringToNativeNode.executeToNative(string);
|
737 | 741 |
|
738 |
| - pointer.writeByte(newByteLength, (byte) 0); // Like MRI |
| 742 | + var encoding = libString.getEncoding(string); |
| 743 | + int minLength = encoding.jcoding.minLength(); |
| 744 | + // Like MRI |
| 745 | + if (minLengthOneProfile.profile(minLength == 1)) { |
| 746 | + pointer.writeByte(newByteLength, (byte) 0); |
| 747 | + } else if (minLength == 2) { |
| 748 | + pointer.writeShort(newByteLength, (short) 0); |
| 749 | + } else if (minLength == 4) { |
| 750 | + pointer.writeInt(newByteLength, 0); |
| 751 | + } else { |
| 752 | + throw CompilerDirectives.shouldNotReachHere(); |
| 753 | + } |
739 | 754 |
|
740 |
| - var newNativeTString = fromNativePointerNode.execute(pointer, 0, newByteLength, |
741 |
| - libString.getTEncoding(string), false); |
| 755 | + var newNativeTString = fromNativePointerNode.execute(pointer, 0, newByteLength, encoding.tencoding, false); |
742 | 756 | string.setTString(newNativeTString);
|
743 | 757 |
|
744 | 758 | return string;
|
@@ -802,7 +816,6 @@ static MutableTruffleString resize(Pointer pointer, int newCapacity, int newByte
|
802 | 816 | RubyLanguage language) {
|
803 | 817 | final Pointer newPointer = newNativeStringPointer(newCapacity, language);
|
804 | 818 | newPointer.writeBytes(0, pointer, 0, Math.min(pointer.getSize(), newCapacity));
|
805 |
| - newPointer.writeByte(newCapacity, (byte) 0); // Like MRI |
806 | 819 |
|
807 | 820 | return fromNativePointerNode.execute(newPointer, 0, newByteLength, tencoding, false);
|
808 | 821 | }
|
@@ -1225,7 +1238,6 @@ public static Pointer allocateAndCopyToNative(AbstractTruffleString tstring, Tru
|
1225 | 1238 | int capacity, TruffleString.CopyToNativeMemoryNode copyToNativeMemoryNode, RubyLanguage language) {
|
1226 | 1239 | final Pointer pointer = newNativeStringPointer(capacity, language);
|
1227 | 1240 | copyToNativeMemoryNode.execute(tstring, 0, pointer, 0, capacity, tencoding);
|
1228 |
| - pointer.writeByte(capacity, (byte) 0); // Like MRI |
1229 | 1241 | return pointer;
|
1230 | 1242 | }
|
1231 | 1243 |
|
|
0 commit comments