@@ -278,10 +278,8 @@ void fx_Enumerator(txMachine* the)
278278 txSlot * iterator ;
279279 txSlot * result ;
280280 txSlot * slot ;
281- txSlot * list ;
282- txSlot * item ;
283- txSlot * instance ;
284- txSlot * * address ;
281+ txSlot * keys ;
282+ txSlot * visited ;
285283
286284 mxPush (mxEnumeratorFunction );
287285 fxGetID (the , mxID (_prototype ));
@@ -293,78 +291,85 @@ void fx_Enumerator(txMachine* the)
293291 slot = fxNextBooleanProperty (the , slot , 0 , mxID (_done ), XS_DONT_DELETE_FLAG | XS_DONT_SET_FLAG );
294292 slot = fxNextSlotProperty (the , iterator , the -> stack , mxID (_result ), XS_GET_ONLY );
295293 mxPop ();
296- list = slot -> next = fxNewSlot (the );
297- list -> flag = XS_GET_ONLY ;
298- list -> ID = mxID (_iterable );
299- list -> kind = mxThis -> kind ;
300- list -> value = mxThis -> value ;
301- if (!mxIsReference (list ))
302- return ;
303- instance = list -> value .reference ;
304- item = list ;
305- mxPushUndefined ();
306- result = the -> stack ;
307- for (;;) {
308- txSlot * at = fxNewInstance (the );
309- mxBehaviorOwnKeys (the , instance , XS_EACH_NAME_FLAG , at );
310- address = & at -> next ;
311- while ((at = * address )) {
312- if (mxBehaviorGetOwnProperty (the , instance , at -> value .at .id , at -> value .at .index , result )) {
313- slot = list -> next ;
314- while ((slot )) {
315- if ((at -> value .at .id == slot -> value .at .id ) && (at -> value .at .index == slot -> value .at .index ))
316- break ;
317- slot = slot -> next ;
318- }
319- if (slot )
320- address = & (at -> next );
321- else {
322- * address = at -> next ;
323- item = item -> next = at ;
324- item -> next = C_NULL ;
325- item -> flag = result -> flag ;
326- }
327- }
328- else
329- address = & (at -> next );
330- }
331- mxPop ();
332- if (mxBehaviorGetPrototype (the , instance , result ))
333- instance = result -> value .reference ;
334- else
335- break ;
336- }
294+
295+ slot = slot -> next = fxNewSlot (the );
296+ slot -> flag = XS_GET_ONLY ;
297+ slot -> ID = mxID (_iterable );
298+ slot -> kind = mxThis -> kind ;
299+ slot -> value = mxThis -> value ;
300+ if (!mxIsReference (slot ))
301+ return ;
302+
303+ keys = fxNewInstance (the );
304+ mxBehaviorOwnKeys (the , slot -> value .reference , XS_EACH_NAME_FLAG , keys );
305+ slot = slot -> next = fxNewSlot (the );
306+ slot -> flag = XS_GET_ONLY ;
307+ slot -> kind = XS_REFERENCE_KIND ;
308+ slot -> value .reference = keys ;
309+ mxPop ();
310+
311+ visited = fxNewInstance (the );
312+ slot = slot -> next = fxNewSlot (the );
313+ slot -> flag = XS_GET_ONLY ;
314+ slot -> kind = XS_REFERENCE_KIND ;
315+ slot -> value .reference = visited ;
337316 mxPop ();
338- address = & list -> next ;
339- while ((slot = * address )) {
340- if (slot -> flag & XS_DONT_ENUM_FLAG ) {
341- * address = slot -> next ;
342- }
343- else {
344- txID id = slot -> value .at .id ;
345- txIndex index = slot -> value .at .index ;
346- fxKeyAt (the , id , index , slot );
347- address = & (slot -> next );
348- }
349- }
350317}
351318
352319void fx_Enumerator_next (txMachine * the )
353320{
354321 txSlot * iterator = fxGetInstance (the , mxThis );
355322 txSlot * result = iterator -> next ;
356323 txSlot * iterable = result -> next ;
357- txSlot * index = iterable -> next ;
358- txSlot * value = result -> value .reference -> next ;
359- txSlot * done = value -> next ;
360- if (index ) {
361- value -> kind = index -> kind ;
362- value -> value = index -> value ;
363- iterable -> next = index -> next ;
324+ txSlot * at = C_NULL ;
325+ if (mxIsReference (iterable )) {
326+ txSlot * instance = iterable -> value .reference ;
327+ txSlot * keys = iterable -> next ;
328+ txSlot * visited = keys -> next ;
329+ txSlot * slot ;
330+ txSlot * former ;
331+
332+ keys = keys -> value .reference ;
333+ visited = visited -> value .reference ;
334+
335+ mxPushUndefined ();
336+ slot = the -> stack ;
337+ again :
338+ while ((at = keys -> next )) {
339+ if (mxBehaviorGetOwnProperty (the , instance , at -> value .at .id , at -> value .at .index , slot )) {
340+ txSlot * * address = & (visited -> next );
341+ while ((former = * address )) {
342+ if ((at -> value .at .id == former -> value .at .id ) && (at -> value .at .index == former -> value .at .index ))
343+ break ;
344+ address = & (former -> next );
345+ }
346+ if (!former ) {
347+ * address = at ;
348+ keys -> next = at -> next ;
349+ at -> next = NULL ;
350+ if (!(slot -> flag & XS_DONT_ENUM_FLAG )) {
351+ fxKeyAt (the , at -> value .at .id , at -> value .at .index , result -> value .reference -> next );
352+ break ;
353+ }
354+ }
355+ else
356+ keys -> next = at -> next ;
357+ }
358+ else
359+ keys -> next = at -> next ;
360+ }
361+ if (!at ) {
362+ if (mxBehaviorGetPrototype (the , instance , slot )) {
363+ iterable -> value .reference = instance = slot -> value .reference ;
364+ mxBehaviorOwnKeys (the , instance , XS_EACH_NAME_FLAG , keys );
365+ goto again ;
366+ }
367+ }
368+ mxPop ();
364369 }
365- else {
366- value -> kind = XS_UNDEFINED_KIND ;
367- done -> value .boolean = 1 ;
370+ if (! at ) {
371+ result -> value . reference -> next -> kind = XS_UNDEFINED_KIND ;
372+ result -> value . reference -> next -> next -> value .boolean = 1 ;
368373 }
369374 mxResult -> kind = result -> kind ;
370375 mxResult -> value = result -> value ;
0 commit comments