@@ -3200,42 +3200,43 @@ public Object stringByteSubstring(Object string, Object range, Object length) {
3200
3200
@ ImportStatic (StringGuards .class )
3201
3201
public static abstract class StringChrAtPrimitiveNode extends CoreMethodArrayArgumentsNode {
3202
3202
3203
- @ Child private StringByteSubstringPrimitiveNode stringByteSubstringNode = StringByteSubstringPrimitiveNode .create ();
3204
-
3205
3203
@ Specialization (guards = "indexOutOfBounds(string, byteIndex)" )
3206
3204
public Object stringChrAtOutOfBounds (DynamicObject string , int byteIndex ) {
3207
3205
return nil ();
3208
3206
}
3209
3207
3210
3208
@ Specialization (guards = { "!indexOutOfBounds(string, byteIndex)" , "isSingleByteOptimizable(string, singleByteOptimizableNode)" })
3211
3209
public Object stringChrAtSingleByte (DynamicObject string , int byteIndex ,
3210
+ @ Cached ("create()" ) StringByteSubstringPrimitiveNode stringByteSubstringNode ,
3212
3211
@ Cached ("create()" ) RopeNodes .SingleByteOptimizableNode singleByteOptimizableNode ) {
3213
3212
return stringByteSubstringNode .executeStringByteSubstring (string , byteIndex , 1 );
3214
3213
}
3215
3214
3216
3215
@ Specialization (guards = { "!indexOutOfBounds(string, byteIndex)" , "!isSingleByteOptimizable(string, singleByteOptimizableNode)" })
3217
3216
public Object stringChrAt (DynamicObject string , int byteIndex ,
3217
+ @ Cached ("create()" ) EncodingNodes .GetActualEncodingNode getActualEncodingNode ,
3218
3218
@ Cached ("create()" ) RopeNodes .BytesNode bytesNode ,
3219
3219
@ Cached ("create()" ) RopeNodes .CalculateCharacterLengthNode calculateCharacterLengthNode ,
3220
3220
@ Cached ("create()" ) RopeNodes .CodeRangeNode codeRangeNode ,
3221
- @ Cached ("create()" ) RopeNodes .SingleByteOptimizableNode singleByteOptimizableNode ) {
3222
- // Taken from Rubinius's Character::create_from.
3223
-
3221
+ @ Cached ("create()" ) RopeNodes .SingleByteOptimizableNode singleByteOptimizableNode ,
3222
+ @ Cached ("create()" ) MakeStringNode makeStringNode ) {
3224
3223
final Rope rope = rope (string );
3224
+ final Encoding encoding = getActualEncodingNode .execute (rope );
3225
3225
final int end = rope .byteLength ();
3226
- final int c = calculateCharacterLengthNode .characterLength (rope .getEncoding (), codeRangeNode .execute (rope ),
3227
- bytesNode .execute (rope ), byteIndex , end );
3226
+ final byte [] bytes = bytesNode .execute (rope );
3227
+ final int c = calculateCharacterLengthNode .characterLength (encoding , codeRangeNode .execute (rope ),
3228
+ bytes , byteIndex , end );
3228
3229
3229
3230
if (!StringSupport .MBCLEN_CHARFOUND_P (c )) {
3230
3231
return nil ();
3231
3232
}
3232
3233
3233
- final int n = StringSupport .MBCLEN_CHARFOUND_LEN (c );
3234
- if (n + byteIndex > end ) {
3234
+ if (c + byteIndex > end ) {
3235
3235
return nil ();
3236
3236
}
3237
3237
3238
- return stringByteSubstringNode .executeStringByteSubstring (string , byteIndex , n );
3238
+ return makeStringNode .executeMake (
3239
+ ArrayUtils .extractRange (bytes , byteIndex , byteIndex + c ), encoding , CR_UNKNOWN );
3239
3240
}
3240
3241
3241
3242
protected static boolean indexOutOfBounds (DynamicObject string , int byteIndex ) {
0 commit comments