Fix iterator to mark opaque state (341877, r=igor).

This commit is contained in:
brendan%mozilla.org 2006-06-18 02:04:40 +00:00
Родитель 5c99361c4e
Коммит 3b45f3b63c
4 изменённых файлов: 53 добавлений и 2 удалений

Просмотреть файл

@ -76,6 +76,33 @@ extern const char js_throw_str[]; /* from jsscan.h */
#error JS_INITIAL_NSLOTS must be greater than JSSLOT_ITER_FLAGS. #error JS_INITIAL_NSLOTS must be greater than JSSLOT_ITER_FLAGS.
#endif #endif
static uint32
iterator_mark(JSContext *cx, JSObject *obj, void *arg)
{
jsval state, parent;
JSObject *iterable;
/* Avoid double work if js_CloseNativeIterator was called on obj. */
state = obj->slots[JSSLOT_ITER_STATE];
if (JSVAL_IS_VOID(state))
return 0;
parent = obj->slots[JSSLOT_PARENT];
if (!JSVAL_IS_NULL(state) && !JSVAL_IS_PRIMITIVE(parent)) {
iterable = JSVAL_TO_OBJECT(parent);
#if JS_HAS_XML_SUPPORT
if ((JSVAL_TO_INT(obj->slots[JSSLOT_ITER_FLAGS]) & JSITER_FOREACH) &&
OBJECT_IS_XML(cx, iterable)) {
((JSXMLObjectOps *) iterable->map->ops)->
enumerateValues(cx, iterable, JSENUMERATE_MARK, &state,
NULL, NULL);
} else
#endif
OBJ_ENUMERATE(cx, iterable, JSENUMERATE_MARK, &state, NULL);
}
return 0;
}
static void static void
iterator_close(JSContext *cx, JSObject *obj) iterator_close(JSContext *cx, JSObject *obj)
{ {
@ -110,7 +137,8 @@ JSExtendedClass js_IteratorClass = {
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator), JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator),
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS }, NULL, NULL, NULL, NULL,
NULL, NULL, iterator_mark, NULL },
NULL, NULL, NULL, iterator_close, NULL, NULL, NULL, iterator_close,
JSCLASS_NO_RESERVED_MEMBERS JSCLASS_NO_RESERVED_MEMBERS
}; };

Просмотреть файл

@ -3793,6 +3793,22 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
JS_free(cx, state); JS_free(cx, state);
*statep = JSVAL_NULL; *statep = JSVAL_NULL;
break; break;
case JSENUMERATE_MARK:
state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep);
ida = state->ida;
length = ida->length;
for (i = 0; i < length; i++) {
jsid id;
id = ida->vector[i];
if (JSID_IS_ATOM(id)) {
GC_MARK_ATOM(cx, JSID_TO_ATOM(id));
} else if (JSID_IS_OBJECT(id)) {
GC_MARK(cx, JSID_TO_OBJECT(id), "ida->vector[i]");
}
}
break;
} }
return JS_TRUE; return JS_TRUE;
} }

Просмотреть файл

@ -119,7 +119,8 @@ typedef enum JSAccessMode {
typedef enum JSIterateOp { typedef enum JSIterateOp {
JSENUMERATE_INIT, /* Create new iterator state */ JSENUMERATE_INIT, /* Create new iterator state */
JSENUMERATE_NEXT, /* Iterate once */ JSENUMERATE_NEXT, /* Iterate once */
JSENUMERATE_DESTROY /* Destroy iterator state */ JSENUMERATE_DESTROY, /* Destroy iterator state */
JSENUMERATE_MARK /* mark opaque iterator state */
} JSIterateOp; } JSIterateOp;
/* Struct typedefs. */ /* Struct typedefs. */

Просмотреть файл

@ -5151,6 +5151,9 @@ xml_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
} }
*statep = JSVAL_NULL; *statep = JSVAL_NULL;
break; break;
case JSENUMERATE_MARK:
break;
} }
return JS_TRUE; return JS_TRUE;
} }
@ -5310,6 +5313,9 @@ xml_enumerateValues(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
} }
*statep = JSVAL_NULL; *statep = JSVAL_NULL;
break; break;
case JSENUMERATE_MARK:
break;
} }
return JS_TRUE; return JS_TRUE;
} }