25
25
*/
26
26
package com .oracle .graal .python .builtins .objects .common ;
27
27
28
+ import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_BYTE_ARRAY_REALLOC ;
28
29
import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_BYTE_ARRAY_TO_NATIVE ;
30
+ import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_DOUBLE_ARRAY_REALLOC ;
29
31
import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_DOUBLE_ARRAY_TO_NATIVE ;
32
+ import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_INT_ARRAY_REALLOC ;
30
33
import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_INT_ARRAY_TO_NATIVE ;
34
+ import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_LONG_ARRAY_REALLOC ;
31
35
import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_LONG_ARRAY_TO_NATIVE ;
36
+ import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_OBJECT_ARRAY_REALLOC ;
32
37
import static com .oracle .graal .python .builtins .objects .cext .capi .NativeCAPISymbols .FUN_PY_TRUFFLE_OBJECT_ARRAY_TO_NATIVE ;
33
38
import static com .oracle .graal .python .nodes .SpecialMethodNames .__EQ__ ;
34
39
import static com .oracle .graal .python .nodes .SpecialMethodNames .__GE__ ;
35
40
import static com .oracle .graal .python .nodes .SpecialMethodNames .__GT__ ;
36
41
import static com .oracle .graal .python .nodes .SpecialMethodNames .__LE__ ;
37
42
import static com .oracle .graal .python .nodes .SpecialMethodNames .__LT__ ;
38
- import static com .oracle .graal .python .runtime .exception .PythonErrorType .BufferError ;
39
43
import static com .oracle .graal .python .runtime .exception .PythonErrorType .MemoryError ;
40
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .OverflowError ;
41
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .SystemError ;
@@ -3321,6 +3325,7 @@ public static CreateEmptyNode create() {
3321
3325
}
3322
3326
3323
3327
@ GenerateUncached
3328
+ @ ImportStatic (ListStorageType .class )
3324
3329
public abstract static class EnsureCapacityNode extends SequenceStorageBaseNode {
3325
3330
3326
3331
public abstract SequenceStorage execute (SequenceStorage s , int cap );
@@ -3345,18 +3350,63 @@ static BasicSequenceStorage doManaged(BasicSequenceStorage s, int cap,
3345
3350
}
3346
3351
}
3347
3352
3348
- @ Specialization
3349
- static NativeSequenceStorage doNative (@ SuppressWarnings ("unused" ) NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3350
- @ Cached PRaiseNode raise ) {
3351
- if (s .getElementType () == Byte ) {
3352
- // TODO: (mq) need to check for the number of ob_exports, i.e. reference counter.
3353
- // (mq) for the time being we will assume that native storage is exported, i.e.
3354
- // `ob_export > 0`.
3355
- raise .raise (BufferError , ErrorMessages .EXPORTS_CANNOT_RESIZE );
3356
- }
3357
- // TODO re-allocate native memory
3358
- CompilerDirectives .transferToInterpreterAndInvalidate ();
3359
- throw new UnsupportedOperationException ();
3353
+ @ Specialization (guards = "s.getElementType() == Byte" )
3354
+ static NativeSequenceStorage doNativeByte (NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3355
+ @ Shared ("i" ) @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
3356
+ @ Exclusive @ Cached PCallCapiFunction callCapiFunction ,
3357
+ @ Shared ("r" ) @ Cached PRaiseNode raiseNode ) {
3358
+ return reallocNativeSequenceStorage (s , cap , lib , callCapiFunction , raiseNode , FUN_PY_TRUFFLE_BYTE_ARRAY_REALLOC );
3359
+ }
3360
+
3361
+ @ Specialization (guards = "s.getElementType() == Int" )
3362
+ static NativeSequenceStorage doNativeInt (NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3363
+ @ Shared ("i" ) @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
3364
+ @ Exclusive @ Cached PCallCapiFunction callCapiFunction ,
3365
+ @ Shared ("r" ) @ Cached PRaiseNode raiseNode ) {
3366
+ return reallocNativeSequenceStorage (s , cap , lib , callCapiFunction , raiseNode , FUN_PY_TRUFFLE_INT_ARRAY_REALLOC );
3367
+ }
3368
+
3369
+ @ Specialization (guards = "s.getElementType() == Long" )
3370
+ static NativeSequenceStorage doNativeLong (NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3371
+ @ Shared ("i" ) @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
3372
+ @ Exclusive @ Cached PCallCapiFunction callCapiFunction ,
3373
+ @ Shared ("r" ) @ Cached PRaiseNode raiseNode ) {
3374
+ return reallocNativeSequenceStorage (s , cap , lib , callCapiFunction , raiseNode , FUN_PY_TRUFFLE_LONG_ARRAY_REALLOC );
3375
+ }
3376
+
3377
+ @ Specialization (guards = "s.getElementType() == Double" )
3378
+ static NativeSequenceStorage doNativeDouble (NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3379
+ @ Shared ("i" ) @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
3380
+ @ Exclusive @ Cached PCallCapiFunction callCapiFunction ,
3381
+ @ Shared ("r" ) @ Cached PRaiseNode raiseNode ) {
3382
+ return reallocNativeSequenceStorage (s , cap , lib , callCapiFunction , raiseNode , FUN_PY_TRUFFLE_DOUBLE_ARRAY_REALLOC );
3383
+ }
3384
+
3385
+ @ Specialization (guards = "s.getElementType() == Generic" )
3386
+ static NativeSequenceStorage doNativeObject (NativeSequenceStorage s , @ SuppressWarnings ("unused" ) int cap ,
3387
+ @ Shared ("i" ) @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
3388
+ @ Exclusive @ Cached PCallCapiFunction callCapiFunction ,
3389
+ @ Shared ("r" ) @ Cached PRaiseNode raiseNode ) {
3390
+ return reallocNativeSequenceStorage (s , cap , lib , callCapiFunction , raiseNode , FUN_PY_TRUFFLE_OBJECT_ARRAY_REALLOC );
3391
+ }
3392
+
3393
+ private static NativeSequenceStorage reallocNativeSequenceStorage (NativeSequenceStorage s , int requestedCapacity , InteropLibrary lib , PCallCapiFunction callCapiFunction , PRaiseNode raiseNode ,
3394
+ String function ) {
3395
+ if (requestedCapacity > s .getCapacity ()) {
3396
+ int newCapacity ;
3397
+ try {
3398
+ newCapacity = Math .max (16 , PythonUtils .multiplyExact (requestedCapacity , 2 ));
3399
+ } catch (OverflowException e ) {
3400
+ newCapacity = requestedCapacity ;
3401
+ }
3402
+ Object ptr = callCapiFunction .call (function , s .getPtr (), newCapacity );
3403
+ if (lib .isNull (ptr )) {
3404
+ throw raiseNode .raise (MemoryError );
3405
+ }
3406
+ s .setPtr (ptr );
3407
+ s .setCapacity (newCapacity );
3408
+ }
3409
+ return s ;
3360
3410
}
3361
3411
}
3362
3412
@@ -3543,22 +3593,22 @@ public DeleteNode(NormalizeIndexNode normalizeIndexNode, String keyTypeErrorMess
3543
3593
3544
3594
@ Specialization
3545
3595
protected void doScalarInt (VirtualFrame frame , SequenceStorage storage , int idx ) {
3546
- getGetItemScalarNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3596
+ getDeleteItemNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3547
3597
}
3548
3598
3549
3599
@ Specialization
3550
3600
protected void doScalarLong (VirtualFrame frame , SequenceStorage storage , long idx ) {
3551
- getGetItemScalarNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3601
+ getDeleteItemNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3552
3602
}
3553
3603
3554
3604
@ Specialization
3555
3605
protected void doScalarPInt (VirtualFrame frame , SequenceStorage storage , PInt idx ) {
3556
- getGetItemScalarNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3606
+ getDeleteItemNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3557
3607
}
3558
3608
3559
3609
@ Specialization (guards = "!isPSlice(idx)" )
3560
3610
protected void doScalarGeneric (VirtualFrame frame , SequenceStorage storage , Object idx ) {
3561
- getGetItemScalarNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3611
+ getDeleteItemNode ().execute (storage , normalizeIndex (frame , idx , storage ));
3562
3612
}
3563
3613
3564
3614
@ Specialization
@@ -3571,7 +3621,7 @@ protected void doSlice(SequenceStorage storage, PSlice slice,
3571
3621
SliceInfo unadjusted = unpack .execute (sliceCast .execute (slice ));
3572
3622
SliceInfo info = adjustIndices .execute (len , unadjusted );
3573
3623
try {
3574
- getGetItemSliceNode ().execute (storage , info );
3624
+ getDeleteSliceNode ().execute (storage , info );
3575
3625
} catch (SequenceStoreException e ) {
3576
3626
CompilerDirectives .transferToInterpreterAndInvalidate ();
3577
3627
throw new IllegalStateException ();
@@ -3587,15 +3637,15 @@ protected void doInvalidKey(@SuppressWarnings("unused") SequenceStorage storage,
3587
3637
throw raiseNode .raise (TypeError , keyTypeErrorMessage , key );
3588
3638
}
3589
3639
3590
- private DeleteItemNode getGetItemScalarNode () {
3640
+ private DeleteItemNode getDeleteItemNode () {
3591
3641
if (deleteItemNode == null ) {
3592
3642
CompilerDirectives .transferToInterpreterAndInvalidate ();
3593
3643
deleteItemNode = insert (DeleteItemNode .create ());
3594
3644
}
3595
3645
return deleteItemNode ;
3596
3646
}
3597
3647
3598
- private DeleteSliceNode getGetItemSliceNode () {
3648
+ private DeleteSliceNode getDeleteSliceNode () {
3599
3649
if (deleteSliceNode == null ) {
3600
3650
CompilerDirectives .transferToInterpreterAndInvalidate ();
3601
3651
deleteSliceNode = insert (DeleteSliceNode .create ());
@@ -3993,23 +4043,47 @@ public final SequenceStorage execute(SequenceStorage storage, int index, Object
3993
4043
3994
4044
protected abstract SequenceStorage execute (SequenceStorage storage , int index , Object value , boolean recursive );
3995
4045
4046
+ @ Specialization
4047
+ protected static SequenceStorage doStorage (EmptySequenceStorage storage , int index , Object value , boolean recursive ,
4048
+ @ Cached InsertItemNode recursiveNode ) {
4049
+ if (!recursive ) {
4050
+ throw CompilerDirectives .shouldNotReachHere ();
4051
+ }
4052
+ SequenceStorage newStorage = storage .generalizeFor (value , null );
4053
+ return recursiveNode .execute (newStorage , index , value , false );
4054
+ }
4055
+
3996
4056
@ Specialization (limit = "MAX_ARRAY_STORAGES" , guards = {"storage.getClass() == cachedClass" })
3997
- protected static SequenceStorage doStorage (SequenceStorage storage , int index , Object value , boolean recursive ,
4057
+ protected static SequenceStorage doStorage (BasicSequenceStorage storage , int index , Object value , boolean recursive ,
3998
4058
@ Cached InsertItemNode recursiveNode ,
3999
4059
@ Cached ("storage.getClass()" ) Class <? extends SequenceStorage > cachedClass ) {
4000
4060
try {
4001
4061
cachedClass .cast (storage ).insertItem (index , value );
4002
4062
return storage ;
4003
4063
} catch (SequenceStoreException e ) {
4004
4064
if (!recursive ) {
4005
- CompilerDirectives .transferToInterpreterAndInvalidate ();
4006
- throw new IllegalStateException ();
4065
+ throw CompilerDirectives .shouldNotReachHere ();
4007
4066
}
4008
4067
SequenceStorage newStorage = cachedClass .cast (storage ).generalizeFor (value , null );
4009
4068
return recursiveNode .execute (newStorage , index , value , false );
4010
4069
}
4011
4070
}
4012
4071
4072
+ @ Specialization
4073
+ protected static SequenceStorage doStorage (NativeSequenceStorage storage , int index , Object value , @ SuppressWarnings ("unused" ) boolean recursive ,
4074
+ @ Cached EnsureCapacityNode ensureCapacityNode ,
4075
+ @ Cached GetItemScalarNode getItem ,
4076
+ @ Cached SetItemScalarNode setItem ) {
4077
+ int newLength = storage .length () + 1 ;
4078
+ ensureCapacityNode .execute (storage , newLength );
4079
+ for (int i = storage .length (); i > index ; i --) {
4080
+ setItem .execute (storage , i , getItem .execute (storage , i - 1 ));
4081
+ }
4082
+ setItem .execute (storage , index , value );
4083
+ storage .setNewLength (newLength );
4084
+ return storage ;
4085
+ }
4086
+
4013
4087
public static InsertItemNode create () {
4014
4088
return InsertItemNodeGen .create ();
4015
4089
}
0 commit comments