42
42
import static com .oracle .graal .python .nodes .SpecialMethodNames .__SETITEM__ ;
43
43
import static com .oracle .graal .python .runtime .exception .PythonErrorType .KeyError ;
44
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
45
+ import static com .oracle .graal .python .runtime .exception .PythonErrorType .RuntimeError ;
45
46
46
47
import java .util .List ;
47
48
51
52
import com .oracle .graal .python .builtins .PythonBuiltins ;
52
53
import com .oracle .graal .python .builtins .objects .PNone ;
53
54
import com .oracle .graal .python .builtins .objects .PNotImplemented ;
55
+ import com .oracle .graal .python .builtins .objects .common .EconomicMapStorage ;
54
56
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes ;
55
57
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes .GetDictStorageNode ;
56
58
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes .SetDictStorageNode ;
57
59
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
58
60
import com .oracle .graal .python .builtins .objects .common .HashingStorage .DictEntry ;
59
61
import com .oracle .graal .python .builtins .objects .common .HashingStorage .StorageSupplier ;
60
62
import com .oracle .graal .python .builtins .objects .common .HashingStorageLibrary ;
63
+ import com .oracle .graal .python .builtins .objects .common .HashingStorageLibrary .HashingStorageIterator ;
61
64
import com .oracle .graal .python .builtins .objects .common .SequenceNodes ;
62
65
import com .oracle .graal .python .builtins .objects .function .PArguments ;
63
66
import com .oracle .graal .python .builtins .objects .function .PBuiltinFunction ;
@@ -452,8 +455,10 @@ public abstract static class ClearNode extends PythonUnaryBuiltinNode {
452
455
453
456
@ Specialization (limit = "3" )
454
457
public PDict clear (PDict dict ,
455
- @ CachedLibrary ("dict.getDictStorage()" ) HashingStorageLibrary lib ) {
456
- lib .clear (dict .getDictStorage ());
458
+ @ CachedLibrary ("dict.getDictStorage()" ) HashingStorageLibrary lib ,
459
+ @ Cached SetDictStorageNode setStorage ) {
460
+ HashingStorage newStorage = lib .clear (dict .getDictStorage ());
461
+ setStorage .execute (dict , newStorage );
457
462
return dict ;
458
463
}
459
464
}
@@ -498,7 +503,7 @@ public Object update(VirtualFrame frame, PDict self, @SuppressWarnings("unused")
498
503
return PNone .NONE ;
499
504
}
500
505
501
- @ Specialization (guards = {"isDict (args)" , "kwargs.length == 0" })
506
+ @ Specialization (guards = {"isDictButNotEconomicMap (args, getStorage )" , "kwargs.length == 0" })
502
507
public Object updateDict (PDict self , Object [] args , @ SuppressWarnings ("unused" ) PKeyword [] kwargs ,
503
508
@ CachedLibrary (limit = "1" ) HashingStorageLibrary lib ,
504
509
@ Cached GetDictStorageNode getStorage ,
@@ -508,7 +513,7 @@ public Object updateDict(PDict self, Object[] args, @SuppressWarnings("unused")
508
513
return PNone .NONE ;
509
514
}
510
515
511
- @ Specialization (guards = {"isDict (args)" , "kwargs.length > 0" })
516
+ @ Specialization (guards = {"isDictButNotEconomicMap (args, getStorage )" , "kwargs.length > 0" })
512
517
public Object updateDict (VirtualFrame frame , PDict self , Object [] args , PKeyword [] kwargs ,
513
518
@ CachedLibrary (limit = "1" ) HashingStorageLibrary lib ,
514
519
@ Cached HashingStorage .InitNode initNode ,
@@ -520,6 +525,45 @@ public Object updateDict(VirtualFrame frame, PDict self, Object[] args, PKeyword
520
525
return PNone .NONE ;
521
526
}
522
527
528
+ @ Specialization (guards = {"isDictEconomicMap(args, getStorage)" , "kwargs.length == 0" }, limit = "1" )
529
+ public Object updateDict (PDict self , Object [] args , @ SuppressWarnings ("unused" ) PKeyword [] kwargs ,
530
+ @ Cached GetDictStorageNode getStorage ,
531
+ @ Cached SetDictStorageNode setStorage ,
532
+ @ CachedLibrary ("getStorage.execute(self)" ) HashingStorageLibrary libSelf ,
533
+ @ CachedLibrary (limit = "1" ) HashingStorageLibrary libOther ) {
534
+ HashingStorage newStorage = addAll (self , (PDict ) args [0 ], getStorage , libSelf , libOther );
535
+ setStorage .execute (self , newStorage );
536
+ return PNone .NONE ;
537
+ }
538
+
539
+ @ Specialization (guards = {"isDictEconomicMap(args, getStorage)" , "kwargs.length > 0" }, limit = "1" )
540
+ public Object updateDict (VirtualFrame frame , PDict self , Object [] args , PKeyword [] kwargs ,
541
+ @ Cached GetDictStorageNode getStorage ,
542
+ @ Cached SetDictStorageNode setStorage ,
543
+ @ CachedLibrary ("getStorage.execute(self)" ) HashingStorageLibrary libSelf ,
544
+ @ CachedLibrary (limit = "1" ) HashingStorageLibrary libOther ,
545
+ @ Cached HashingStorage .InitNode initNode ) {
546
+ HashingStorage newStorage = addAll (self , (PDict ) args [0 ], getStorage , libSelf , libOther );
547
+ newStorage = libOther .addAllToOther (initNode .execute (frame , PNone .NO_VALUE , kwargs ), newStorage );
548
+ setStorage .execute (self , newStorage );
549
+ return PNone .NONE ;
550
+ }
551
+
552
+ private HashingStorage addAll (PDict self , PDict other , GetDictStorageNode getStorage , HashingStorageLibrary libSelf , HashingStorageLibrary libOther ) throws PException {
553
+ HashingStorage selfStorage = getStorage .execute (self );
554
+ HashingStorage otherStorage = getStorage .execute (other );
555
+ HashingStorageIterator <DictEntry > itOther = libOther .entries (otherStorage ).iterator ();
556
+ HashingStorage newStorage = selfStorage ;
557
+ while (itOther .hasNext ()) {
558
+ DictEntry next = itOther .next ();
559
+ newStorage = libSelf .setItem (selfStorage , next .key , next .value );
560
+ if (otherStorage != getStorage .execute (other )) {
561
+ throw raise (RuntimeError , ErrorMessages .MUTATED_DURING_UPDATE , "dict" );
562
+ }
563
+ }
564
+ return newStorage ;
565
+ }
566
+
523
567
@ Specialization (guards = {"args.length == 1" , "!isDict(args)" , "hasKeysAttr(args, libArg)" })
524
568
public Object updateMapping (VirtualFrame frame , PDict self , Object [] args , PKeyword [] kwargs ,
525
569
@ SuppressWarnings ("unused" ) @ CachedLibrary (limit = "1" ) PythonObjectLibrary libArg ,
@@ -570,6 +614,14 @@ protected boolean isDict(Object[] args) {
570
614
return args .length == 1 && args [0 ] instanceof PDict ;
571
615
}
572
616
617
+ protected boolean isDictEconomicMap (Object [] args , GetDictStorageNode getStorage ) {
618
+ return args .length == 1 && args [0 ] instanceof PDict && getStorage .execute ((PDict ) args [0 ]) instanceof EconomicMapStorage ;
619
+ }
620
+
621
+ protected boolean isDictButNotEconomicMap (Object [] args , GetDictStorageNode getStorage ) {
622
+ return args .length == 1 && args [0 ] instanceof PDict && !(getStorage .execute ((PDict ) args [0 ]) instanceof EconomicMapStorage );
623
+ }
624
+
573
625
protected boolean isSeq (Object [] args ) {
574
626
return args .length == 1 && args [0 ] instanceof PSequence ;
575
627
}
0 commit comments