155
155
import com .oracle .truffle .api .dsl .TypeSystemReference ;
156
156
import com .oracle .truffle .api .frame .VirtualFrame ;
157
157
import com .oracle .truffle .api .library .CachedLibrary ;
158
+ import com .oracle .truffle .api .nodes .Node ;
158
159
import com .oracle .truffle .api .profiles .BranchProfile ;
159
160
import com .oracle .truffle .api .profiles .ConditionProfile ;
160
161
import com .oracle .truffle .api .profiles .LoopConditionProfile ;
@@ -2249,42 +2250,82 @@ protected String make(String self, int width, String fill) {
2249
2250
2250
2251
}
2251
2252
2253
+ public abstract static class StrGetItemNodeWithSlice extends Node {
2254
+
2255
+ public abstract String execute (String value , SliceInfo info );
2256
+
2257
+ static boolean isEmptySlice (SliceInfo s ) {
2258
+ int step = s .step ;
2259
+ int start = s .start ;
2260
+ int stop = s .stop ;
2261
+ return (step >= 0 && stop <= start ) || (step <= 0 && stop >= start );
2262
+ }
2263
+
2264
+ static boolean isSimpleSlice (SliceInfo s ) {
2265
+ return s .step == 1 && s .stop > s .start ;
2266
+ }
2267
+
2268
+ @ Specialization (guards = "isSimpleSlice(slice)" )
2269
+ static String doStepOneStopGtStart (String value , SliceInfo slice ) {
2270
+ return getSubString (value , slice .start , slice .stop );
2271
+ }
2272
+
2273
+ @ Specialization (guards = "isEmptySlice(slice)" )
2274
+ static String doEmptySlice (@ SuppressWarnings ("unused" ) String value , @ SuppressWarnings ("unused" ) SliceInfo slice ) {
2275
+ return "" ;
2276
+ }
2277
+
2278
+ @ Specialization (guards = {"step == slice.step" , "!isSimpleSlice(slice)" , "!isEmptySlice(slice)" }, limit = "1" )
2279
+ static String doGenericCachedStep (String value , SliceInfo slice ,
2280
+ @ Cached ("slice.step" ) int step ,
2281
+ @ Shared ("loop" ) @ Cached ("createCountingProfile()" ) LoopConditionProfile loopProfile ,
2282
+ @ Shared ("len" ) @ Cached LenOfRangeNode sliceLen ) {
2283
+ int len = sliceLen .len (slice );
2284
+ int start = slice .start ;
2285
+ char [] newChars = new char [len ];
2286
+ int j = 0 ;
2287
+ loopProfile .profileCounted (len );
2288
+ for (int i = start ; loopProfile .inject (j < len ); i += step ) {
2289
+ newChars [j ++] = value .charAt (i );
2290
+ }
2291
+ return PythonUtils .newString (newChars );
2292
+ }
2293
+
2294
+ @ Specialization (replaces = "doGenericCachedStep" , guards = {"!isSimpleSlice(slice)" , "!isEmptySlice(slice)" })
2295
+ static String doGeneric (String value , SliceInfo slice ,
2296
+ @ Shared ("loop" ) @ Cached ("createCountingProfile()" ) LoopConditionProfile loopProfile ,
2297
+ @ Shared ("len" ) @ Cached LenOfRangeNode sliceLen ) {
2298
+ return doGenericCachedStep (value , slice , slice .step , loopProfile , sliceLen );
2299
+ }
2300
+
2301
+ @ TruffleBoundary (allowInlining = true )
2302
+ private static String getSubString (String origin , int start , int stop ) {
2303
+ return origin .substring (start , stop );
2304
+ }
2305
+ }
2306
+
2252
2307
@ Builtin (name = __GETITEM__ , minNumOfPositionalArgs = 2 )
2253
2308
@ GenerateNodeFactory
2254
2309
@ TypeSystemReference (PythonArithmeticTypes .class )
2255
2310
public abstract static class StrGetItemNode extends PythonBinaryBuiltinNode {
2256
2311
2257
- @ Specialization
2258
- public String doString (String primary , PSlice slice ,
2312
+ @ Specialization (guards = "isString(primary)" )
2313
+ public String doString (Object primary , PSlice slice ,
2314
+ @ Cached CastToJavaStringNode castToJavaString ,
2259
2315
@ Cached CoerceToIntSlice sliceCast ,
2260
2316
@ Cached ComputeIndices compute ,
2261
- @ Cached LenOfRangeNode sliceLen ) {
2262
- SliceInfo info = compute .execute (sliceCast .execute (slice ), primary .length ());
2263
- final int sliceLength = sliceLen .len (info );
2264
- final int start = info .start ;
2265
- int stop = info .stop ;
2266
- int step = info .step ;
2267
-
2268
- if (step > 0 && stop < start ) {
2269
- stop = start ;
2270
- }
2271
- if (step == 1 ) {
2272
- return getSubString (primary , start , stop );
2273
- } else {
2274
- char [] newChars = new char [sliceLength ];
2275
- int j = 0 ;
2276
- for (int i = start ; j < sliceLength ; i += step ) {
2277
- newChars [j ++] = primary .charAt (i );
2278
- }
2279
-
2280
- return PythonUtils .newString (newChars );
2281
- }
2317
+ @ Cached StrGetItemNodeWithSlice getItemNodeWithSlice ) {
2318
+ String str = castToJavaString .execute (primary );
2319
+ SliceInfo info = compute .execute (sliceCast .execute (slice ), str .length ());
2320
+ return getItemNodeWithSlice .execute (str , info );
2282
2321
}
2283
2322
2284
- @ Specialization (limit = "getCallSiteInlineCacheMaxDepth()" )
2285
- public String doString (VirtualFrame frame , String primary , Object idx ,
2323
+ @ Specialization (guards = {"!isPSlice(idx)" , "isString(primary)" }, limit = "getCallSiteInlineCacheMaxDepth()" )
2324
+ public String doString (VirtualFrame frame , Object primary , Object idx ,
2325
+ @ Cached CastToJavaStringNode castToJavaString ,
2286
2326
@ Cached ("createBinaryProfile()" ) ConditionProfile hasFrame ,
2287
2327
@ CachedLibrary ("idx" ) PythonObjectLibrary lib ) {
2328
+ String str = castToJavaString .execute (primary );
2288
2329
int index ;
2289
2330
if (hasFrame .profile (frame != null )) {
2290
2331
index = lib .asSizeWithState (idx , PArguments .getThreadState (frame ));
@@ -2293,9 +2334,9 @@ public String doString(VirtualFrame frame, String primary, Object idx,
2293
2334
}
2294
2335
try {
2295
2336
if (index < 0 ) {
2296
- index += primary .length ();
2337
+ index += str .length ();
2297
2338
}
2298
- return charAtToString (primary , index );
2339
+ return charAtToString (str , index );
2299
2340
} catch (StringIndexOutOfBoundsException | ArithmeticException e ) {
2300
2341
throw raise (IndexError , ErrorMessages .STRING_INDEX_OUT_OF_RANGE );
2301
2342
}
@@ -2307,17 +2348,10 @@ Object doGeneric(Object self, Object other) {
2307
2348
return PNotImplemented .NOT_IMPLEMENTED ;
2308
2349
}
2309
2350
2310
- @ TruffleBoundary
2311
- private static String getSubString (String origin , int start , int stop ) {
2312
- char [] chars = new char [stop - start ];
2313
- origin .getChars (start , stop , chars , 0 );
2314
- return new String (chars );
2315
- }
2316
-
2317
2351
@ TruffleBoundary
2318
2352
private static String charAtToString (String primary , int index ) {
2319
- char charactor = primary .charAt (index );
2320
- return new String (new char []{charactor });
2353
+ char character = primary .charAt (index );
2354
+ return new String (new char []{character });
2321
2355
}
2322
2356
}
2323
2357
0 commit comments