зеркало из https://github.com/mozilla/gecko-dev.git
new Iterator() always constructs the default iterator. bug=354945 r=brendan
This commit is contained in:
Родитель
19c7d67134
Коммит
6fea546cc2
111
js/src/jsiter.c
111
js/src/jsiter.c
|
@ -122,10 +122,43 @@ JSClass js_IteratorClass = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
Iterator(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
InitNativeIterator(JSContext *cx, JSObject *iterobj, JSObject *obj, uintN flags)
|
||||||
{
|
{
|
||||||
|
jsval state;
|
||||||
|
JSBool ok;
|
||||||
|
|
||||||
|
JS_ASSERT(JSVAL_TO_PRIVATE(iterobj->slots[JSSLOT_CLASS]) ==
|
||||||
|
&js_IteratorClass);
|
||||||
|
|
||||||
|
/* Initialize iterobj in case of enumerate hook failure. */
|
||||||
|
iterobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);
|
||||||
|
iterobj->slots[JSSLOT_ITER_STATE] = JSVAL_NULL;
|
||||||
|
iterobj->slots[JSSLOT_ITER_FLAGS] = INT_TO_JSVAL(flags);
|
||||||
|
if (!js_RegisterCloseableIterator(cx, iterobj))
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
ok =
|
||||||
|
#if JS_HAS_XML_SUPPORT
|
||||||
|
((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, obj))
|
||||||
|
? ((JSXMLObjectOps *) obj->map->ops)->
|
||||||
|
enumerateValues(cx, obj, JSENUMERATE_INIT, &state, NULL, NULL)
|
||||||
|
:
|
||||||
|
#endif
|
||||||
|
OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, NULL);
|
||||||
|
if (!ok)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
iterobj->slots[JSSLOT_ITER_STATE] = state;
|
||||||
|
return JS_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSBool
|
||||||
|
Iterator(JSContext *cx, JSObject *iterobj, uintN argc, jsval *argv, jsval *rval)
|
||||||
|
{
|
||||||
|
JSObject *obj;
|
||||||
|
JSBool keyonly;
|
||||||
|
jsid id;
|
||||||
jsval fval;
|
jsval fval;
|
||||||
const jsid id = ATOM_TO_JSID(cx->runtime->atomState.iteratorAtom);
|
|
||||||
|
|
||||||
/* XXX work around old valueOf call hidden beneath js_ValueToObject */
|
/* XXX work around old valueOf call hidden beneath js_ValueToObject */
|
||||||
if (!JSVAL_IS_PRIMITIVE(argv[0])) {
|
if (!JSVAL_IS_PRIMITIVE(argv[0])) {
|
||||||
|
@ -134,8 +167,17 @@ Iterator(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||||
obj = js_ValueToNonNullObject(cx, argv[0]);
|
obj = js_ValueToNonNullObject(cx, argv[0]);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
argv[0] = OBJECT_TO_JSVAL(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cx->fp->flags & JSFRAME_CONSTRUCTING) {
|
||||||
|
keyonly = JS_FALSE;
|
||||||
|
return js_ValueToBoolean(cx, argv[1], &keyonly) &&
|
||||||
|
InitNativeIterator(cx, iterobj, obj,
|
||||||
|
keyonly ? 0 : JSITER_FOREACH);
|
||||||
|
}
|
||||||
|
|
||||||
|
id = ATOM_TO_JSID(cx->runtime->atomState.iteratorAtom);
|
||||||
return JS_GetMethodById(cx, obj, id, &obj, &fval) &&
|
return JS_GetMethodById(cx, obj, id, &obj, &fval) &&
|
||||||
js_InternalCall(cx, obj, fval, argc - 1, argv + 1, rval);
|
js_InternalCall(cx, obj, fval, argc - 1, argv + 1, rval);
|
||||||
}
|
}
|
||||||
|
@ -287,8 +329,6 @@ JSBool
|
||||||
js_NewNativeIterator(JSContext *cx, JSObject *obj, uintN flags, jsval *vp)
|
js_NewNativeIterator(JSContext *cx, JSObject *obj, uintN flags, jsval *vp)
|
||||||
{
|
{
|
||||||
JSObject *iterobj;
|
JSObject *iterobj;
|
||||||
jsval state;
|
|
||||||
JSBool ok;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create iterobj with a NULL parent to ensure that we use the correct
|
* Create iterobj with a NULL parent to ensure that we use the correct
|
||||||
|
@ -302,26 +342,7 @@ js_NewNativeIterator(JSContext *cx, JSObject *obj, uintN flags, jsval *vp)
|
||||||
/* Store iterobj in *vp to protect it from GC (callers must root vp). */
|
/* Store iterobj in *vp to protect it from GC (callers must root vp). */
|
||||||
*vp = OBJECT_TO_JSVAL(iterobj);
|
*vp = OBJECT_TO_JSVAL(iterobj);
|
||||||
|
|
||||||
/* Initialize iterobj in case of enumerate hook failure. */
|
return InitNativeIterator(cx, iterobj, obj, flags);
|
||||||
iterobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj);
|
|
||||||
iterobj->slots[JSSLOT_ITER_STATE] = JSVAL_NULL;
|
|
||||||
iterobj->slots[JSSLOT_ITER_FLAGS] = INT_TO_JSVAL(flags);
|
|
||||||
if (!js_RegisterCloseableIterator(cx, iterobj))
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
ok =
|
|
||||||
#if JS_HAS_XML_SUPPORT
|
|
||||||
((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, obj))
|
|
||||||
? ((JSXMLObjectOps *) obj->map->ops)->
|
|
||||||
enumerateValues(cx, obj, JSENUMERATE_INIT, &state, NULL, NULL)
|
|
||||||
:
|
|
||||||
#endif
|
|
||||||
OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, NULL);
|
|
||||||
if (!ok)
|
|
||||||
return JS_FALSE;
|
|
||||||
|
|
||||||
iterobj->slots[JSSLOT_ITER_STATE] = state;
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintN
|
uintN
|
||||||
|
@ -363,23 +384,6 @@ js_CloseNativeIterator(JSContext *cx, JSObject *iterobj)
|
||||||
js_CloseIteratorState(cx, iterobj);
|
js_CloseIteratorState(cx, iterobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSBool
|
|
||||||
js_DefaultIterator(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|
||||||
jsval *rval)
|
|
||||||
{
|
|
||||||
JSBool keyonly;
|
|
||||||
|
|
||||||
if (OBJ_GET_CLASS(cx, obj) == &js_IteratorClass) {
|
|
||||||
*rval = OBJECT_TO_JSVAL(obj);
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
keyonly = JS_FALSE;
|
|
||||||
if (argc != 0 && !js_ValueToBoolean(cx, argv[0], &keyonly))
|
|
||||||
return JS_FALSE;
|
|
||||||
return js_NewNativeIterator(cx, obj, keyonly ? 0 : JSITER_FOREACH, rval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inline expansion of Iterator, with extra logic to constrain the result of
|
* Inline expansion of Iterator, with extra logic to constrain the result of
|
||||||
* ToObject(v).__iterator__.
|
* ToObject(v).__iterator__.
|
||||||
|
@ -402,29 +406,26 @@ js_ValueToIterator(JSContext *cx, jsval v, uintN flags)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = BOOLEAN_TO_JSVAL((flags & JSITER_FOREACH) == 0);
|
|
||||||
|
|
||||||
JS_PUSH_SINGLE_TEMP_ROOT(cx, obj, &tvr);
|
JS_PUSH_SINGLE_TEMP_ROOT(cx, obj, &tvr);
|
||||||
if (!JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), &obj, &fval))
|
if (!JS_GetMethodById(cx, obj, ATOM_TO_JSID(atom), &obj, &fval))
|
||||||
goto bad;
|
goto bad;
|
||||||
if (JSVAL_IS_VOID(fval)) {
|
if (JSVAL_IS_VOID(fval)) {
|
||||||
/* Fail over to the default native iterator, called directly. */
|
/* Fail over to the default enumerating native iterator. */
|
||||||
if (!js_DefaultIterator(cx, obj, 1, &arg, &rval))
|
if (!js_NewNativeIterator(cx, obj,
|
||||||
|
(flags & JSITER_FOREACH) | JSITER_ENUMERATE,
|
||||||
|
&rval)) {
|
||||||
goto bad;
|
goto bad;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
arg = BOOLEAN_TO_JSVAL((flags & JSITER_FOREACH) == 0);
|
||||||
|
if (!js_InternalInvoke(cx, obj, fval, JSINVOKE_ITERATOR, 1, &arg,
|
||||||
|
&rval)) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
if (JSVAL_IS_PRIMITIVE(rval))
|
if (JSVAL_IS_PRIMITIVE(rval))
|
||||||
goto bad_iterator;
|
goto bad_iterator;
|
||||||
iterobj = JSVAL_TO_OBJECT(rval);
|
|
||||||
JS_ASSERT(OBJ_GET_CLASS(cx, iterobj) == &js_IteratorClass);
|
|
||||||
iterobj->slots[JSSLOT_ITER_FLAGS] |= INT_TO_JSVAL(JSITER_ENUMERATE);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!js_InternalInvoke(cx, obj, fval, JSINVOKE_ITERATOR, 1, &arg, &rval))
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
if (JSVAL_IS_PRIMITIVE(rval))
|
|
||||||
goto bad_iterator;
|
|
||||||
|
|
||||||
iterobj = JSVAL_TO_OBJECT(rval);
|
iterobj = JSVAL_TO_OBJECT(rval);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -61,10 +61,6 @@ js_CloseNativeIterator(JSContext *cx, JSObject *iterobj);
|
||||||
extern void
|
extern void
|
||||||
js_CloseIteratorState(JSContext *cx, JSObject *iterobj);
|
js_CloseIteratorState(JSContext *cx, JSObject *iterobj);
|
||||||
|
|
||||||
extern JSBool
|
|
||||||
js_DefaultIterator(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|
||||||
jsval *rval);
|
|
||||||
|
|
||||||
extern JSObject *
|
extern JSObject *
|
||||||
js_ValueToIterator(JSContext *cx, jsval v, uintN flags);
|
js_ValueToIterator(JSContext *cx, jsval v, uintN flags);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче