зеркало из https://github.com/mozilla/gecko-dev.git
Bug 783829 - Factor out NativeIteratorNext. r=efaust
This commit is contained in:
Родитель
56b818b46f
Коммит
73077d1cd2
|
@ -849,6 +849,38 @@ js::IteratorConstructor(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
NativeIteratorNext(JSContext *cx, NativeIterator *ni, MutableHandleValue rval, bool *done)
|
||||
{
|
||||
*done = false;
|
||||
|
||||
if (ni->props_cursor >= ni->props_end) {
|
||||
*done = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (MOZ_LIKELY(ni->isKeyIter())) {
|
||||
rval.setString(*ni->current());
|
||||
ni->incCursor();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Non-standard Iterator for "for each"
|
||||
RootedId id(cx);
|
||||
RootedValue current(cx, StringValue(*ni->current()));
|
||||
if (!ValueToId<CanGC>(cx, current, &id))
|
||||
return false;
|
||||
ni->incCursor();
|
||||
RootedObject obj(cx, ni->obj);
|
||||
if (!JSObject::getGeneric(cx, obj, obj, id, rval))
|
||||
return false;
|
||||
|
||||
// JS 1.7 only: for each (let [k, v] in obj)
|
||||
if (ni->flags & JSITER_KEYVALUE)
|
||||
return NewKeyValuePair(cx, id, rval, rval);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
IsIterator(HandleValue v)
|
||||
{
|
||||
|
@ -862,14 +894,19 @@ iterator_next_impl(JSContext *cx, CallArgs args)
|
|||
|
||||
RootedObject thisObj(cx, &args.thisv().toObject());
|
||||
|
||||
if (!IteratorMore(cx, thisObj, args.rval()))
|
||||
return false;
|
||||
NativeIterator *ni = thisObj.as<PropertyIteratorObject>()->getNativeIterator();
|
||||
RootedValue value(cx);
|
||||
bool done;
|
||||
if (!NativeIteratorNext(cx, ni, &value, &done))
|
||||
return false;
|
||||
|
||||
if (args.rval().isMagic(JS_NO_ITER_VALUE)) {
|
||||
// Use old iterator protocol for compatibility reasons.
|
||||
if (done) {
|
||||
ThrowStopIteration(cx);
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1226,40 +1263,20 @@ bool
|
|||
js::IteratorMore(JSContext *cx, HandleObject iterobj, MutableHandleValue rval)
|
||||
{
|
||||
/* Fast path for native iterators */
|
||||
NativeIterator *ni = nullptr;
|
||||
if (iterobj->is<PropertyIteratorObject>()) {
|
||||
/* Key iterators are handled by fast-paths. */
|
||||
ni = iterobj->as<PropertyIteratorObject>().getNativeIterator();
|
||||
if (ni->props_cursor >= ni->props_end) {
|
||||
NativeIterator *ni = iterobj->as<PropertyIteratorObject>().getNativeIterator();
|
||||
bool done;
|
||||
if (!NativeIteratorNext(cx, ni, rval, &done))
|
||||
return false;
|
||||
|
||||
if (done)
|
||||
rval.setMagic(JS_NO_ITER_VALUE);
|
||||
return true;
|
||||
}
|
||||
if (ni->isKeyIter()) {
|
||||
rval.setString(*ni->current());
|
||||
ni->incCursor();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We're reentering below and can call anything. */
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
/* Fetch and cache the next value from the iterator. */
|
||||
if (ni) {
|
||||
MOZ_ASSERT(!ni->isKeyIter());
|
||||
RootedId id(cx);
|
||||
RootedValue current(cx, StringValue(*ni->current()));
|
||||
if (!ValueToId<CanGC>(cx, current, &id))
|
||||
return false;
|
||||
ni->incCursor();
|
||||
RootedObject obj(cx, ni->obj);
|
||||
if (!JSObject::getGeneric(cx, obj, obj, id, rval))
|
||||
return false;
|
||||
if ((ni->flags & JSITER_KEYVALUE) && !NewKeyValuePair(cx, id, rval, rval))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Call the iterator object's .next method. */
|
||||
if (!JSObject::getProperty(cx, iterobj, iterobj, cx->names().next, rval))
|
||||
return false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче