@@ -1140,12 +1140,12 @@ protected SequenceStorage doSliceSequence(SequenceStorage storage, PSlice slice,
1140
1140
int len = lenNode .execute (storage );
1141
1141
SliceInfo info = adjustIndices .execute (len , unadjusted );
1142
1142
try {
1143
- setItemSliceNode .execute (storage , info , sequence );
1143
+ setItemSliceNode .execute (storage , info , sequence , true );
1144
1144
return storage ;
1145
1145
} catch (SequenceStoreException e ) {
1146
1146
generalizeProfile .enter ();
1147
1147
SequenceStorage generalized = generalizeStore (storage , e .getIndicationValue ());
1148
- setItemSliceNode .execute (generalized , info , sequence );
1148
+ setItemSliceNode .execute (generalized , info , sequence , false );
1149
1149
return generalized ;
1150
1150
}
1151
1151
}
@@ -1167,12 +1167,12 @@ protected SequenceStorage doSliceGeneric(SequenceStorage storage, PSlice slice,
1167
1167
// must not use iterable again. It could have sice-effects.
1168
1168
PList values = constructListNode .execute (iterable );
1169
1169
try {
1170
- setItemSliceNode .execute (storage , info , values );
1170
+ setItemSliceNode .execute (storage , info , values , true );
1171
1171
return storage ;
1172
1172
} catch (SequenceStoreException e ) {
1173
1173
generalizeProfile .enter ();
1174
1174
SequenceStorage generalized = generalizeStore (storage , e .getIndicationValue ());
1175
- setItemSliceNode .execute (generalized , info , values );
1175
+ setItemSliceNode .execute (generalized , info , values , false );
1176
1176
return generalized ;
1177
1177
}
1178
1178
}
@@ -1321,21 +1321,25 @@ public static SetItemScalarNode create() {
1321
1321
@ ImportStatic ({ListStorageType .class , SequenceStorageBaseNode .class })
1322
1322
public abstract static class SetItemSliceNode extends Node {
1323
1323
1324
- public abstract void execute (SequenceStorage s , SliceInfo info , Object iterable );
1324
+ public abstract void execute (SequenceStorage s , SliceInfo info , Object iterable , boolean canGeneralize );
1325
+
1326
+ public final void execute (SequenceStorage s , SliceInfo info , Object iterable ) {
1327
+ execute (s , info , iterable , true );
1328
+ }
1325
1329
1326
1330
@ Specialization (guards = "hasStorage(seq)" )
1327
- static void doStorage (SequenceStorage s , SliceInfo info , PSequence seq ,
1331
+ static void doStorage (SequenceStorage s , SliceInfo info , PSequence seq , boolean canGeneralize ,
1328
1332
@ Shared ("setStorageSliceNode" ) @ Cached SetStorageSliceNode setStorageSliceNode ,
1329
1333
@ Cached GetSequenceStorageNode getSequenceStorageNode ) {
1330
- setStorageSliceNode .execute (s , info , getSequenceStorageNode .execute (seq ));
1334
+ setStorageSliceNode .execute (s , info , getSequenceStorageNode .execute (seq ), canGeneralize );
1331
1335
}
1332
1336
1333
1337
@ Specialization
1334
- static void doGeneric (SequenceStorage s , SliceInfo info , Object iterable ,
1338
+ static void doGeneric (SequenceStorage s , SliceInfo info , Object iterable , boolean canGeneralize ,
1335
1339
@ Shared ("setStorageSliceNode" ) @ Cached SetStorageSliceNode setStorageSliceNode ,
1336
1340
@ Cached ListNodes .ConstructListNode constructListNode ) {
1337
1341
PList list = constructListNode .execute (iterable );
1338
- setStorageSliceNode .execute (s , info , list .getSequenceStorage ());
1342
+ setStorageSliceNode .execute (s , info , list .getSequenceStorage (), canGeneralize );
1339
1343
}
1340
1344
1341
1345
public static SetItemSliceNode create () {
@@ -1416,10 +1420,10 @@ protected static boolean isBasicSequenceStorage(Object o) {
1416
1420
@ ImportStatic (SequenceStorageBaseNode .class )
1417
1421
abstract static class SetStorageSliceNode extends Node {
1418
1422
1419
- public abstract void execute (SequenceStorage s , SliceInfo info , SequenceStorage iterable );
1423
+ public abstract void execute (SequenceStorage s , SliceInfo info , SequenceStorage iterable , boolean canGeneralize );
1420
1424
1421
1425
@ Specialization (limit = "MAX_ARRAY_STORAGES" , guards = {"self.getClass() == cachedClass" , "self.getClass() == sequence.getClass()" , "replacesWholeSequence(cachedClass, self, info)" })
1422
- static void doWholeSequence (BasicSequenceStorage self , @ SuppressWarnings ("unused" ) SliceInfo info , BasicSequenceStorage sequence ,
1426
+ static void doWholeSequence (BasicSequenceStorage self , @ SuppressWarnings ("unused" ) SliceInfo info , BasicSequenceStorage sequence , @ SuppressWarnings ( "unused" ) boolean canGeneralize ,
1423
1427
@ Cached ("self.getClass()" ) Class <? extends BasicSequenceStorage > cachedClass ) {
1424
1428
BasicSequenceStorage selfProfiled = cachedClass .cast (self );
1425
1429
BasicSequenceStorage otherProfiled = cachedClass .cast (sequence );
@@ -1428,8 +1432,8 @@ static void doWholeSequence(BasicSequenceStorage self, @SuppressWarnings("unused
1428
1432
selfProfiled .minimizeCapacity ();
1429
1433
}
1430
1434
1431
- @ Specialization (guards = {"isDataTypeCompatibleNode.execute(self, values)" , "sinfo.step == 1" })
1432
- static void singleStep (SequenceStorage self , SliceInfo sinfo , SequenceStorage values ,
1435
+ @ Specialization (guards = {"!canGeneralize || isDataTypeCompatibleNode.execute(self, values)" , "sinfo.step == 1" })
1436
+ static void singleStep (SequenceStorage self , SliceInfo sinfo , SequenceStorage values , @ SuppressWarnings ( "unused" ) boolean canGeneralize ,
1433
1437
@ Cached @ SuppressWarnings ("unused" ) IsDataTypeCompatibleNode isDataTypeCompatibleNode ,
1434
1438
@ Cached LenNode lenNode ,
1435
1439
@ Cached SetLenNode setLenNode ,
@@ -1456,8 +1460,8 @@ static void singleStep(SequenceStorage self, SliceInfo sinfo, SequenceStorage va
1456
1460
memoryError , negGrowth , posGrowth , raiseNode );
1457
1461
}
1458
1462
1459
- @ Specialization (guards = {"isDataTypeCompatibleNode.execute(self, values)" , "sinfo.step != 1" })
1460
- static void multiStep (SequenceStorage self , SliceInfo sinfo , SequenceStorage values ,
1463
+ @ Specialization (guards = {"!canGeneralize || isDataTypeCompatibleNode.execute(self, values)" , "sinfo.step != 1" })
1464
+ static void multiStep (SequenceStorage self , SliceInfo sinfo , SequenceStorage values , @ SuppressWarnings ( "unused" ) boolean canGeneralize ,
1461
1465
@ Cached @ SuppressWarnings ("unused" ) IsDataTypeCompatibleNode isDataTypeCompatibleNode ,
1462
1466
@ Cached ConditionProfile wrongLength ,
1463
1467
@ Cached ConditionProfile deleteSlice ,
@@ -1490,8 +1494,8 @@ static void multiStep(SequenceStorage self, SliceInfo sinfo, SequenceStorage val
1490
1494
}
1491
1495
}
1492
1496
1493
- @ Specialization (guards = " !isAssignCompatibleNode.execute(self, sequence)" )
1494
- static void doError (@ SuppressWarnings ("unused" ) SequenceStorage self , @ SuppressWarnings ("unused" ) SliceInfo info , SequenceStorage sequence ,
1497
+ @ Specialization (guards = { "canGeneralize" , " !isAssignCompatibleNode.execute(self, sequence)"} )
1498
+ static void doError (@ SuppressWarnings ("unused" ) SequenceStorage self , @ SuppressWarnings ("unused" ) SliceInfo info , SequenceStorage sequence , @ SuppressWarnings ( "unused" ) boolean canGeneralize ,
1495
1499
@ Cached @ SuppressWarnings ("unused" ) IsAssignCompatibleNode isAssignCompatibleNode ) {
1496
1500
throw new SequenceStoreException (sequence .getIndicativeValue ());
1497
1501
}
@@ -2765,6 +2769,13 @@ static int doGeneric(VirtualFrame frame, SequenceStorage left, Object item,
2765
2769
}
2766
2770
}
2767
2771
2772
+ /**
2773
+ * Generalization node must convert given storage to a storage that is able to be written any
2774
+ * number of any valid elements. I.e., there must be a specialization handling that storage type
2775
+ * in {@link SetItemScalarNode}. Note: it is possible that the RHS of the write may be invalid
2776
+ * element, e.g., large integer when the storage is bytes array storage, but in such case the
2777
+ * {@link SetItemScalarNode} will correctly raise Python level {@code ValueError}.
2778
+ */
2768
2779
public abstract static class GeneralizationNode extends Node {
2769
2780
public abstract SequenceStorage execute (SequenceStorage toGeneralize , Object indicationValue );
2770
2781
@@ -2836,6 +2847,49 @@ public static NoGeneralizationCustomMessageNode create(String msg) {
2836
2847
}
2837
2848
}
2838
2849
2850
+ /**
2851
+ * Byte array is specific that it supports being written using slice from other iterables as
2852
+ * long as the individual elements written can be converted to bytes. Arrays from the array
2853
+ * module do not support this, they can be written only individual elements or slice from other
2854
+ * array of the same type.
2855
+ *
2856
+ * This node works with the assumption that all storages of byte arrays support writing of any
2857
+ * number of bytes. There is no actual generalization of the storage, but instead we tell the
2858
+ * caller that it should try again with the same storage (in the second try, it should try to
2859
+ * write whatever is in RHS no matter of the type of the storage of RHS).
2860
+ *
2861
+ * This is only limitation of this node. Shall we ever want to support byte arrays that can be
2862
+ * backed by different types of storage, we'd only need to change this node to accommodate for
2863
+ * that and return the most generic storage of those.
2864
+ */
2865
+ public static class ByteArrayGeneralizationNode extends GeneralizationNode {
2866
+ public static ByteArrayGeneralizationNode UNCACHED = new ByteArrayGeneralizationNode ();
2867
+
2868
+ public static final GenNodeSupplier SUPPLIER = new GenNodeSupplier () {
2869
+ @ Override
2870
+ public GeneralizationNode getUncached () {
2871
+ return UNCACHED ;
2872
+ }
2873
+
2874
+ @ Override
2875
+ public GeneralizationNode create () {
2876
+ return new ByteArrayGeneralizationNode ();
2877
+ }
2878
+ };
2879
+
2880
+ public static final Supplier <GeneralizationNode > CACHED_SUPPLIER = new Supplier <GeneralizationNode >() {
2881
+ @ Override
2882
+ public GeneralizationNode get () {
2883
+ return new ByteArrayGeneralizationNode ();
2884
+ }
2885
+ };
2886
+
2887
+ @ Override
2888
+ public SequenceStorage execute (SequenceStorage toGeneralize , @ SuppressWarnings ("unused" ) Object indicationValue ) {
2889
+ return toGeneralize ;
2890
+ }
2891
+ }
2892
+
2839
2893
/**
2840
2894
* Implements list generalization rules; previously in 'SequenceStroage.generalizeFor'.
2841
2895
*/
0 commit comments