@@ -91,9 +91,52 @@ function copyPrototype(src, dest, prefix) {
9191 }
9292}
9393
94+ const createSafeIterator = ( factory , next ) => {
95+ class SafeIterator {
96+ constructor ( iterable ) {
97+ this . _iterator = factory ( iterable ) ;
98+ }
99+ next ( ) {
100+ return next ( this . _iterator ) ;
101+ }
102+ [ Symbol . iterator ] ( ) {
103+ return this ;
104+ }
105+ }
106+ Object . setPrototypeOf ( SafeIterator . prototype , null ) ;
107+ Object . freeze ( SafeIterator . prototype ) ;
108+ Object . freeze ( SafeIterator ) ;
109+ return SafeIterator ;
110+ } ;
111+
94112function makeSafe ( unsafe , safe ) {
95- copyProps ( unsafe . prototype , safe . prototype ) ;
113+ if ( Symbol . iterator in unsafe . prototype ) {
114+ const dummy = new unsafe ( ) ;
115+ let next ; // We can reuse the same `next` method.
116+
117+ for ( const key of Reflect . ownKeys ( unsafe . prototype ) ) {
118+ if ( ! Reflect . getOwnPropertyDescriptor ( safe . prototype , key ) ) {
119+ const desc = Reflect . getOwnPropertyDescriptor ( unsafe . prototype , key ) ;
120+ if (
121+ typeof desc . value === 'function' &&
122+ desc . value . length === 0 &&
123+ Symbol . iterator in ( desc . value . call ( dummy ) ?? { } )
124+ ) {
125+ const createIterator = uncurryThis ( desc . value ) ;
126+ next ??= uncurryThis ( createIterator ( dummy ) . next ) ;
127+ const SafeIterator = createSafeIterator ( createIterator , next ) ;
128+ desc . value = function ( ) {
129+ return new SafeIterator ( this ) ;
130+ } ;
131+ }
132+ Reflect . defineProperty ( safe . prototype , key , desc ) ;
133+ }
134+ }
135+ } else {
136+ copyProps ( unsafe . prototype , safe . prototype ) ;
137+ }
96138 copyProps ( unsafe , safe ) ;
139+
97140 Object . setPrototypeOf ( safe . prototype , null ) ;
98141 Object . freeze ( safe . prototype ) ;
99142 Object . freeze ( safe ) ;
0 commit comments