44
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
45
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
46
46
47
- import java .util .Arrays ;
48
-
49
47
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
50
48
import com .oracle .graal .python .builtins .objects .PNone ;
51
49
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .PCallCapiFunction ;
@@ -282,20 +280,20 @@ static String doPSequence(VirtualFrame frame, String self, PSequence sequence,
282
280
return "" ;
283
281
}
284
282
285
- StringBuilder sb = new StringBuilder ();
283
+ StringBuilder sb = StringUtils . newStringBuilder ();
286
284
int i = 0 ;
287
285
288
286
try {
289
287
// manually peel first iteration
290
288
Object item = getItemNode .execute (frame , storage , i );
291
- append (sb , castToJavaStringNode .cast (item , INVALID_SEQ_ITEM , i , item ));
289
+ StringUtils . append (sb , castToJavaStringNode .cast (item , INVALID_SEQ_ITEM , i , item ));
292
290
293
291
for (i = 1 ; i < len ; i ++) {
294
- append (sb , self );
292
+ StringUtils . append (sb , self );
295
293
item = getItemNode .execute (frame , storage , i );
296
- append (sb , castToJavaStringNode .cast (item , INVALID_SEQ_ITEM , i , item ));
294
+ StringUtils . append (sb , castToJavaStringNode .cast (item , INVALID_SEQ_ITEM , i , item ));
297
295
}
298
- return toString (sb );
296
+ return StringUtils . toString (sb );
299
297
} catch (OutOfMemoryError e ) {
300
298
throw raise .raise (MemoryError );
301
299
}
@@ -318,9 +316,9 @@ static String doGeneric(VirtualFrame frame, String string, Object iterable,
318
316
throw raise .raise (PythonBuiltinClassType .TypeError , ErrorMessages .CAN_ONLY_JOIN_ITERABLE );
319
317
}
320
318
try {
321
- StringBuilder str = new StringBuilder ();
319
+ StringBuilder str = StringUtils . newStringBuilder ();
322
320
try {
323
- append (str , checkItem (nextNode .execute (frame , iterator ), 0 , castStrNode , raise ));
321
+ StringUtils . append (str , checkItem (nextNode .execute (frame , iterator ), 0 , castStrNode , raise ));
324
322
} catch (PException e ) {
325
323
e .expectStopIteration (errorProfile1 );
326
324
return "" ;
@@ -332,10 +330,10 @@ static String doGeneric(VirtualFrame frame, String string, Object iterable,
332
330
value = nextNode .execute (frame , iterator );
333
331
} catch (PException e ) {
334
332
e .expectStopIteration (errorProfile2 );
335
- return toString (str );
333
+ return StringUtils . toString (str );
336
334
}
337
- append (str , string );
338
- append (str , checkItem (value , i ++, castStrNode , raise ));
335
+ StringUtils . append (str , string );
336
+ StringUtils . append (str , checkItem (value , i ++, castStrNode , raise ));
339
337
}
340
338
} catch (OutOfMemoryError e ) {
341
339
throw raise .raise (MemoryError );
@@ -350,106 +348,66 @@ private static String checkItem(Object item, int pos, CastToJavaStringNode castN
350
348
}
351
349
}
352
350
353
- @ TruffleBoundary (allowInlining = true )
354
- static StringBuilder append (StringBuilder sb , String o ) {
355
- return sb .append (o );
356
- }
357
-
358
- @ TruffleBoundary (allowInlining = true )
359
- static String toString (StringBuilder sb ) {
360
- return sb .toString ();
361
- }
362
-
363
351
static boolean isExactlyListOrTuple (PythonObjectLibrary lib , IsBuiltinClassProfile tupleProfile , IsBuiltinClassProfile listProfile , PSequence sequence ) {
364
352
Object cls = lib .getLazyPythonClass (sequence );
365
353
return tupleProfile .profileClass (cls , PythonBuiltinClassType .PTuple ) || listProfile .profileClass (cls , PythonBuiltinClassType .PList );
366
354
}
367
355
}
368
356
357
+ @ ImportStatic (PGuards .class )
369
358
public abstract static class SpliceNode extends PNodeWithContext {
370
359
371
- public abstract char [] execute (char [] translatedChars , int i , Object translated );
360
+ public abstract void execute (StringBuilder sb , Object translated );
361
+
362
+ @ Specialization (guards = "isNone(none)" )
363
+ @ SuppressWarnings ("unused" )
364
+ static void doNone (StringBuilder sb , PNone none ) {
365
+ }
372
366
373
367
@ Specialization
374
- static char [] doInt (char [] translatedChars , int i , int translated ,
375
- @ Shared ("raise" ) @ Cached PRaiseNode raise ,
376
- @ Cached BranchProfile ovf ) {
377
- try {
378
- translatedChars [i ] = PInt .charValueExact (translated );
379
- return translatedChars ;
380
- } catch (OverflowException e ) {
381
- ovf .enter ();
382
- throw raiseError (raise );
383
- }
368
+ @ TruffleBoundary (allowInlining = true )
369
+ static void doInt (StringBuilder sb , int translated ) {
370
+ sb .appendCodePoint (translated );
384
371
}
385
372
386
373
@ Specialization
387
- static char [] doLong (char [] translatedChars , int i , long translated ,
374
+ static void doLong (StringBuilder sb , long translated ,
388
375
@ Shared ("raise" ) @ Cached PRaiseNode raise ,
389
- @ Cached BranchProfile ovf ) {
376
+ @ Shared ( "overflow" ) @ Cached BranchProfile ovf ) {
390
377
try {
391
- translatedChars [i ] = PInt .charValueExact (translated );
392
- return translatedChars ;
378
+ doInt (sb , PInt .intValueExact (translated ));
393
379
} catch (OverflowException e ) {
394
380
ovf .enter ();
395
381
throw raiseError (raise );
396
382
}
397
383
}
398
384
399
385
@ Specialization
400
- static char [] doPInt (char [] translatedChars , int i , PInt translated ,
386
+ static void doPInt (StringBuilder sb , PInt translated ,
401
387
@ Shared ("raise" ) @ Cached PRaiseNode raise ,
402
- @ Cached BranchProfile ovf ) {
403
- double doubleValue = translated . doubleValue ();
404
- char t = ( char ) doubleValue ;
405
- if ( t != doubleValue ) {
388
+ @ Shared ( "overflow" ) @ Cached BranchProfile ovf ) {
389
+ try {
390
+ doInt ( sb , translated . intValueExact ()) ;
391
+ } catch ( OverflowException e ) {
406
392
ovf .enter ();
407
393
throw raiseError (raise );
408
394
}
409
- translatedChars [i ] = t ;
410
- return translatedChars ;
411
- }
412
-
413
- @ Specialization (guards = "translated.length() == 1" )
414
- @ TruffleBoundary
415
- static char [] doStringChar (char [] translatedChars , int i , String translated ) {
416
- translatedChars [i ] = translated .charAt (0 );
417
- return translatedChars ;
418
395
}
419
396
420
- @ Specialization (replaces = "doStringChar" )
421
- @ TruffleBoundary
422
- static char [] doString (char [] translatedChars , int i , String translated ) {
423
- int transLen = translated .length ();
424
- if (transLen == 1 ) {
425
- translatedChars [i ] = translated .charAt (0 );
426
- } else if (transLen == 0 ) {
427
- int len = translatedChars .length ;
428
- return Arrays .copyOf (translatedChars , len - 1 );
429
- } else {
430
- int len = translatedChars .length ;
431
- char [] copy = Arrays .copyOf (translatedChars , len + transLen - 1 );
432
- translated .getChars (0 , transLen , copy , i );
433
- return copy ;
434
- }
435
- return translatedChars ;
397
+ @ Specialization
398
+ @ TruffleBoundary (allowInlining = true )
399
+ static void doString (StringBuilder sb , String translated ) {
400
+ sb .append (translated );
436
401
}
437
402
438
- @ Specialization
439
- static char [] doObject (char [] translatedChars , int i , Object translated ,
403
+ @ Specialization ( guards = { "!isInteger(translated)" , "!isPInt(translated)" , "!isNone(translated)" })
404
+ static void doObject (StringBuilder sb , Object translated ,
440
405
@ Shared ("raise" ) @ Cached PRaiseNode raise ,
441
- @ Cached BranchProfile ovf ,
442
406
@ Cached CastToJavaStringNode castToJavaStringNode ) {
443
407
444
- if (translated instanceof Integer || translated instanceof Long ) {
445
- return doLong (translatedChars , i , ((Number ) translated ).longValue (), raise , ovf );
446
- } else if (translated instanceof PInt ) {
447
- return doPInt (translatedChars , i , (PInt ) translated , raise , ovf );
448
- }
449
-
450
408
try {
451
409
String translatedStr = castToJavaStringNode .execute (translated );
452
- return doString (translatedChars , i , translatedStr );
410
+ doString (sb , translatedStr );
453
411
} catch (CannotCastException e ) {
454
412
throw raise .raise (PythonBuiltinClassType .TypeError , ErrorMessages .CHARACTER_MAPPING_MUST_RETURN_INT_NONE_OR_STR );
455
413
}
0 commit comments