зеркало из https://github.com/mozilla/gecko-dev.git
Bug 725907 - for-of improvements, part 1: minor C++ refactoring, rename Iterator to PropertyIteratorObject. r=Waldo.
--HG-- extra : rebase_source : 22a88c4169eba37b61a96dd1ff8507b82765b53e
This commit is contained in:
Родитель
b8e78daacd
Коммит
af800ae65c
|
@ -0,0 +1,38 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef Iterator_inl_h_
|
||||
#define Iterator_inl_h_
|
||||
|
||||
#include "jsiter.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
inline bool
|
||||
JSObject::isPropertyIterator() const
|
||||
{
|
||||
return hasClass(&js::PropertyIteratorObject::class_);
|
||||
}
|
||||
|
||||
inline js::PropertyIteratorObject &
|
||||
JSObject::asPropertyIterator()
|
||||
{
|
||||
JS_ASSERT(isPropertyIterator());
|
||||
return *static_cast<js::PropertyIteratorObject *>(this);
|
||||
}
|
||||
|
||||
js::NativeIterator *
|
||||
js::PropertyIteratorObject::getNativeIterator() const
|
||||
{
|
||||
JS_ASSERT(isPropertyIterator());
|
||||
return static_cast<js::NativeIterator *>(getPrivate());
|
||||
}
|
||||
|
||||
inline void
|
||||
js::PropertyIteratorObject::setNativeIterator(js::NativeIterator *ni)
|
||||
{
|
||||
setPrivate(ni);
|
||||
}
|
||||
|
||||
#endif // Iterator_inl_h_
|
|
@ -36,8 +36,8 @@
|
|||
* MarkString, etc. These functions check if an object is in the compartment
|
||||
* currently being GCed. If it is, they call PushMarkStack. Roots are pushed
|
||||
* this way as well as pointers traversed inside trace hooks (for things like
|
||||
* IteratorClass). It it always valid to call a MarkX function instead of
|
||||
* PushMarkStack, although it may be slower.
|
||||
* PropertyIteratorObjects). It is always valid to call a MarkX function
|
||||
* instead of PushMarkStack, although it may be slower.
|
||||
*
|
||||
* The MarkX functions also handle non-GC object traversal. In this case, they
|
||||
* call a callback for each object visited. This is a recursive process; the
|
||||
|
|
|
@ -1868,7 +1868,7 @@ static JSStdName standard_class_names[] = {
|
|||
#endif
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
{js_InitIteratorClasses, EAGER_ATOM_AND_CLASP(Iterator)},
|
||||
{js_InitIteratorClasses, EAGER_CLASS_ATOM(Iterator), &PropertyIteratorObject::class_},
|
||||
#endif
|
||||
|
||||
/* Typed Arrays */
|
||||
|
|
|
@ -189,7 +189,7 @@ class NativeIterCache
|
|||
static const size_t SIZE = size_t(1) << 8;
|
||||
|
||||
/* Cached native iterators. */
|
||||
JSObject *data[SIZE];
|
||||
PropertyIteratorObject *data[SIZE];
|
||||
|
||||
static size_t getIndex(uint32_t key) {
|
||||
return size_t(key) % SIZE;
|
||||
|
@ -197,7 +197,7 @@ class NativeIterCache
|
|||
|
||||
public:
|
||||
/* Native iterator most recently started. */
|
||||
JSObject *last;
|
||||
PropertyIteratorObject *last;
|
||||
|
||||
NativeIterCache()
|
||||
: last(NULL) {
|
||||
|
@ -209,11 +209,11 @@ class NativeIterCache
|
|||
PodArrayZero(data);
|
||||
}
|
||||
|
||||
JSObject *get(uint32_t key) const {
|
||||
PropertyIteratorObject *get(uint32_t key) const {
|
||||
return data[getIndex(key)];
|
||||
}
|
||||
|
||||
void set(uint32_t key, JSObject *iterobj) {
|
||||
void set(uint32_t key, PropertyIteratorObject *iterobj) {
|
||||
data[getIndex(key)] = iterobj;
|
||||
}
|
||||
};
|
||||
|
@ -1256,7 +1256,7 @@ struct JSContext : js::ContextFriendFields
|
|||
DSTOffsetCache dstOffsetCache;
|
||||
|
||||
/* List of currently active non-escaping enumerators (for-in). */
|
||||
JSObject *enumerators;
|
||||
js::PropertyIteratorObject *enumerators;
|
||||
|
||||
private:
|
||||
/* Innermost-executing generator or null if no generator are executing. */
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "jsscriptinlines.h"
|
||||
#include "jstypedarrayinlines.h"
|
||||
|
||||
#include "builtin/Iterator-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
||||
|
@ -1001,8 +1002,8 @@ JS_STATIC_ASSERT(JSOP_INCNAME_LENGTH == JSOP_NAMEDEC_LENGTH);
|
|||
static inline bool
|
||||
IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
|
||||
{
|
||||
if (iterobj->isIterator()) {
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
if (iterobj->isPropertyIterator()) {
|
||||
NativeIterator *ni = iterobj->asPropertyIterator().getNativeIterator();
|
||||
if (ni->isKeyIter()) {
|
||||
*cond = (ni->props_cursor < ni->props_end);
|
||||
return true;
|
||||
|
@ -1018,8 +1019,8 @@ IteratorMore(JSContext *cx, JSObject *iterobj, bool *cond, Value *rval)
|
|||
static inline bool
|
||||
IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
{
|
||||
if (iterobj->isIterator()) {
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
if (iterobj->isPropertyIterator()) {
|
||||
NativeIterator *ni = iterobj->asPropertyIterator().getNativeIterator();
|
||||
if (ni->isKeyIter()) {
|
||||
JS_ASSERT(ni->props_cursor < ni->props_end);
|
||||
rval->setString(*ni->current());
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "jsinferinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "builtin/Iterator-inl.h"
|
||||
#include "vm/MethodGuard-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
#include "vm/String-inl.h"
|
||||
|
@ -51,36 +52,8 @@ using namespace mozilla;
|
|||
using namespace js;
|
||||
using namespace js::gc;
|
||||
|
||||
static void iterator_finalize(FreeOp *fop, JSObject *obj);
|
||||
static void iterator_trace(JSTracer *trc, JSObject *obj);
|
||||
static JSObject *iterator_iterator(JSContext *cx, HandleObject obj, JSBool keysonly);
|
||||
|
||||
Class js::IteratorClass = {
|
||||
"Iterator",
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator),
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
iterator_finalize,
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* hasInstance */
|
||||
iterator_trace,
|
||||
{
|
||||
NULL, /* equality */
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
iterator_iterator,
|
||||
NULL /* unused */
|
||||
}
|
||||
};
|
||||
|
||||
Class js::ElementIteratorClass = {
|
||||
"ElementIterator",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ElementIteratorObject::NumSlots),
|
||||
|
@ -117,27 +90,6 @@ NativeIterator::mark(JSTracer *trc)
|
|||
MarkObject(trc, &obj, "obj");
|
||||
}
|
||||
|
||||
static void
|
||||
iterator_finalize(FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(obj->isIterator());
|
||||
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
if (ni) {
|
||||
obj->setPrivate(NULL);
|
||||
fop->free_(ni);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iterator_trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
|
||||
if (ni)
|
||||
ni->mark(trc);
|
||||
}
|
||||
|
||||
struct IdHashPolicy {
|
||||
typedef jsid Lookup;
|
||||
static HashNumber hash(jsid id) {
|
||||
|
@ -479,8 +431,8 @@ Compare(T *a, T *b, size_t c)
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline JSObject *
|
||||
NewIteratorObject(JSContext *cx, unsigned flags)
|
||||
static inline PropertyIteratorObject *
|
||||
NewPropertyIteratorObject(JSContext *cx, unsigned flags)
|
||||
{
|
||||
if (flags & JSITER_ENUMERATE) {
|
||||
RootedTypeObject type(cx);
|
||||
|
@ -489,8 +441,8 @@ NewIteratorObject(JSContext *cx, unsigned flags)
|
|||
return NULL;
|
||||
|
||||
RootedShape emptyEnumeratorShape(cx);
|
||||
emptyEnumeratorShape = EmptyShape::getInitialShape(cx, &IteratorClass, NULL, NULL,
|
||||
ITERATOR_FINALIZE_KIND);
|
||||
emptyEnumeratorShape = EmptyShape::getInitialShape(cx, &PropertyIteratorObject::class_,
|
||||
NULL, NULL, ITERATOR_FINALIZE_KIND);
|
||||
if (!emptyEnumeratorShape)
|
||||
return NULL;
|
||||
|
||||
|
@ -500,10 +452,10 @@ NewIteratorObject(JSContext *cx, unsigned flags)
|
|||
return NULL;
|
||||
|
||||
JS_ASSERT(obj->numFixedSlots() == JSObject::ITER_CLASS_NFIXED_SLOTS);
|
||||
return obj;
|
||||
return &obj->asPropertyIterator();
|
||||
}
|
||||
|
||||
return NewBuiltinClassInstance(cx, &IteratorClass);
|
||||
return &NewBuiltinClassInstance(cx, &PropertyIteratorObject::class_)->asPropertyIterator();
|
||||
}
|
||||
|
||||
NativeIterator *
|
||||
|
@ -541,7 +493,7 @@ NativeIterator::init(JSObject *obj, unsigned flags, uint32_t slength, uint32_t k
|
|||
}
|
||||
|
||||
static inline void
|
||||
RegisterEnumerator(JSContext *cx, JSObject *iterobj, NativeIterator *ni)
|
||||
RegisterEnumerator(JSContext *cx, PropertyIteratorObject *iterobj, NativeIterator *ni)
|
||||
{
|
||||
/* Register non-escaping native enumerators (for-in) with the current context. */
|
||||
if (ni->flags & JSITER_ENUMERATE) {
|
||||
|
@ -565,7 +517,7 @@ VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVecto
|
|||
types::MarkTypeObjectFlags(cx, obj, types::OBJECT_FLAG_ITERATED);
|
||||
}
|
||||
|
||||
RootedObject iterobj(cx, NewIteratorObject(cx, flags));
|
||||
Rooted<PropertyIteratorObject *> iterobj(cx, NewPropertyIteratorObject(cx, flags));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
|
||||
|
@ -618,7 +570,7 @@ VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVec
|
|||
types::MarkTypeObjectFlags(cx, obj, types::OBJECT_FLAG_ITERATED);
|
||||
}
|
||||
|
||||
JSObject *iterobj = NewIteratorObject(cx, flags);
|
||||
PropertyIteratorObject *iterobj = NewPropertyIteratorObject(cx, flags);
|
||||
if (!iterobj)
|
||||
return false;
|
||||
|
||||
|
@ -687,7 +639,7 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
|
|||
* objects here, as they are not inserted into the cache and
|
||||
* will result in a miss.
|
||||
*/
|
||||
JSObject *last = cx->runtime->nativeIterCache.last;
|
||||
PropertyIteratorObject *last = cx->runtime->nativeIterCache.last;
|
||||
JSObject *proto = obj->getProto();
|
||||
if (last) {
|
||||
NativeIterator *lastni = last->getNativeIterator();
|
||||
|
@ -726,7 +678,7 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
|
|||
pobj = pobj->getProto();
|
||||
} while (pobj);
|
||||
|
||||
JSObject *iterobj = cx->runtime->nativeIterCache.get(key);
|
||||
PropertyIteratorObject *iterobj = cx->runtime->nativeIterCache.get(key);
|
||||
if (iterobj) {
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
if (!(ni->flags & (JSITER_ACTIVE|JSITER_UNREUSABLE)) &&
|
||||
|
@ -773,7 +725,7 @@ GetIterator(JSContext *cx, HandleObject obj, unsigned flags, Value *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
JSObject *iterobj = &vp->toObject();
|
||||
PropertyIteratorObject *iterobj = &vp->toObject().asPropertyIterator();
|
||||
|
||||
/* Cache the iterator object if possible. */
|
||||
if (shapes.length())
|
||||
|
@ -829,8 +781,11 @@ iterator_next(JSContext *cx, unsigned argc, Value *vp)
|
|||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
RootedObject thisObj(cx);
|
||||
if (!NonGenericMethodGuard(cx, args, iterator_next, &IteratorClass, thisObj.address()))
|
||||
if (!NonGenericMethodGuard(cx, args, iterator_next, &PropertyIteratorObject::class_,
|
||||
thisObj.address()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!thisObj)
|
||||
return true;
|
||||
|
||||
|
@ -852,6 +807,49 @@ static JSFunctionSpec iterator_methods[] = {
|
|||
JS_FS_END
|
||||
};
|
||||
|
||||
void
|
||||
PropertyIteratorObject::trace(JSTracer *trc, JSObject *obj)
|
||||
{
|
||||
if (NativeIterator *ni = obj->asPropertyIterator().getNativeIterator())
|
||||
ni->mark(trc);
|
||||
}
|
||||
|
||||
void
|
||||
PropertyIteratorObject::finalize(FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
if (NativeIterator *ni = obj->asPropertyIterator().getNativeIterator()) {
|
||||
obj->asPropertyIterator().setNativeIterator(NULL);
|
||||
fop->free_(ni);
|
||||
}
|
||||
}
|
||||
|
||||
Class PropertyIteratorObject::class_ = {
|
||||
"Iterator",
|
||||
JSCLASS_IMPLEMENTS_BARRIERS |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_PropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
NULL, /* checkAccess */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* hasInstance */
|
||||
trace,
|
||||
{
|
||||
NULL, /* equality */
|
||||
NULL, /* outerObject */
|
||||
NULL, /* innerObject */
|
||||
iterator_iterator,
|
||||
NULL /* unused */
|
||||
}
|
||||
};
|
||||
|
||||
#if JS_HAS_GENERATORS
|
||||
static JSBool
|
||||
CloseGenerator(JSContext *cx, JSObject *genobj);
|
||||
|
@ -905,9 +903,9 @@ js::CloseIterator(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||
|
||||
if (obj->isIterator()) {
|
||||
if (obj->isPropertyIterator()) {
|
||||
/* Remove enumerators from the active list, which is a stack. */
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
NativeIterator *ni = obj->asPropertyIterator().getNativeIterator();
|
||||
|
||||
if (ni->flags & JSITER_ENUMERATE) {
|
||||
JS_ASSERT(cx->enumerators == obj);
|
||||
|
@ -945,8 +943,8 @@ js::UnwindIteratorForException(JSContext *cx, JSObject *obj)
|
|||
void
|
||||
js::UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
if (obj->isIterator()) {
|
||||
NativeIterator *ni = obj->getNativeIterator();
|
||||
if (obj->isPropertyIterator()) {
|
||||
NativeIterator *ni = obj->asPropertyIterator().getNativeIterator();
|
||||
if (ni->flags & JSITER_ENUMERATE) {
|
||||
JS_ASSERT(cx->enumerators == obj);
|
||||
cx->enumerators = ni->next;
|
||||
|
@ -975,7 +973,7 @@ template<typename StringPredicate>
|
|||
static bool
|
||||
SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate predicate)
|
||||
{
|
||||
JSObject *iterobj = cx->enumerators;
|
||||
PropertyIteratorObject *iterobj = cx->enumerators;
|
||||
while (iterobj) {
|
||||
again:
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
|
@ -1172,9 +1170,9 @@ js_IteratorMore(JSContext *cx, HandleObject iterobj, Value *rval)
|
|||
{
|
||||
/* Fast path for native iterators */
|
||||
NativeIterator *ni = NULL;
|
||||
if (iterobj->isIterator()) {
|
||||
if (iterobj->isPropertyIterator()) {
|
||||
/* Key iterators are handled by fast-paths. */
|
||||
ni = iterobj->getNativeIterator();
|
||||
ni = iterobj->asPropertyIterator().getNativeIterator();
|
||||
bool more = ni->props_cursor < ni->props_end;
|
||||
if (ni->isKeyIter() || !more) {
|
||||
rval->setBoolean(more);
|
||||
|
@ -1248,12 +1246,12 @@ JSBool
|
|||
js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
||||
{
|
||||
/* Fast path for native iterators */
|
||||
if (iterobj->isIterator()) {
|
||||
if (iterobj->isPropertyIterator()) {
|
||||
/*
|
||||
* Implement next directly as all the methods of the native iterator are
|
||||
* read-only and permanent.
|
||||
*/
|
||||
NativeIterator *ni = iterobj->getNativeIterator();
|
||||
NativeIterator *ni = iterobj->asPropertyIterator().getNativeIterator();
|
||||
if (ni->isKeyIter()) {
|
||||
JS_ASSERT(ni->props_cursor < ni->props_end);
|
||||
*rval = StringValue(*ni->current());
|
||||
|
@ -1548,7 +1546,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
|
|||
gen->regs = cx->regs();
|
||||
|
||||
cx->enterGenerator(gen); /* OOM check above. */
|
||||
JSObject *enumerators = cx->enumerators;
|
||||
PropertyIteratorObject *enumerators = cx->enumerators;
|
||||
cx->enumerators = gen->enumerators;
|
||||
|
||||
ok = RunScript(cx, fp->script(), fp);
|
||||
|
@ -1703,7 +1701,8 @@ static JSFunctionSpec generator_methods[] = {
|
|||
static bool
|
||||
InitIteratorClass(JSContext *cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
RootedObject iteratorProto(cx, global->createBlankPrototype(cx, &IteratorClass));
|
||||
Rooted<JSObject*> iteratorProto(cx,
|
||||
global->createBlankPrototype(cx, &PropertyIteratorObject::class_));
|
||||
if (!iteratorProto)
|
||||
return false;
|
||||
|
||||
|
@ -1713,7 +1712,7 @@ InitIteratorClass(JSContext *cx, Handle<GlobalObject*> global)
|
|||
return false;
|
||||
ni->init(NULL, 0 /* flags */, 0, 0);
|
||||
|
||||
iteratorProto->setNativeIterator(ni);
|
||||
iteratorProto->asPropertyIterator().setNativeIterator(ni);
|
||||
|
||||
RootedFunction ctor(cx);
|
||||
ctor = global->createConstructor(cx, Iterator, CLASS_NAME(cx, Iterator), 2);
|
||||
|
|
|
@ -28,16 +28,17 @@
|
|||
|
||||
namespace js {
|
||||
|
||||
struct NativeIterator {
|
||||
struct NativeIterator
|
||||
{
|
||||
HeapPtrObject obj;
|
||||
HeapPtr<JSFlatString> *props_array;
|
||||
HeapPtr<JSFlatString> *props_cursor;
|
||||
HeapPtr<JSFlatString> *props_end;
|
||||
const Shape **shapes_array;
|
||||
uint32_t shapes_length;
|
||||
uint32_t shapes_key;
|
||||
uint32_t flags;
|
||||
JSObject *next; /* Forms cx->enumerators list, garbage otherwise. */
|
||||
uint32_t shapes_length;
|
||||
uint32_t shapes_key;
|
||||
uint32_t flags;
|
||||
PropertyIteratorObject *next; /* Forms cx->enumerators list, garbage otherwise. */
|
||||
|
||||
bool isKeyIter() const { return (flags & JSITER_FOREACH) == 0; }
|
||||
|
||||
|
@ -69,7 +70,21 @@ struct NativeIterator {
|
|||
void mark(JSTracer *trc);
|
||||
};
|
||||
|
||||
class ElementIteratorObject : public JSObject {
|
||||
class PropertyIteratorObject : public JSObject
|
||||
{
|
||||
public:
|
||||
static Class class_;
|
||||
|
||||
inline NativeIterator *getNativeIterator() const;
|
||||
inline void setNativeIterator(js::NativeIterator *ni);
|
||||
|
||||
private:
|
||||
static void trace(JSTracer *trc, JSObject *obj);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
};
|
||||
|
||||
class ElementIteratorObject : public JSObject
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
TargetSlot,
|
||||
|
@ -229,7 +244,8 @@ Next(JSContext *cx, HandleObject iter, Value *vp)
|
|||
* and the failure is allowed to propagate on cx, as in this example if DoStuff
|
||||
* fails. In that case, ForOfIterator's destructor does all necessary cleanup.
|
||||
*/
|
||||
class ForOfIterator {
|
||||
class ForOfIterator
|
||||
{
|
||||
private:
|
||||
JSContext *cx;
|
||||
RootedObject iterator;
|
||||
|
@ -305,7 +321,7 @@ struct JSGenerator
|
|||
js::HeapPtrObject obj;
|
||||
JSGeneratorState state;
|
||||
js::FrameRegs regs;
|
||||
JSObject *enumerators;
|
||||
js::PropertyIteratorObject *enumerators;
|
||||
JSGenerator *prevGenerator;
|
||||
js::StackFrame *fp;
|
||||
js::HeapValue stackSnapshot[1];
|
||||
|
|
|
@ -209,7 +209,6 @@ extern Class DateClass;
|
|||
extern Class ErrorClass;
|
||||
extern Class ElementIteratorClass;
|
||||
extern Class GeneratorClass;
|
||||
extern Class IteratorClass;
|
||||
extern Class JSONClass;
|
||||
extern Class MathClass;
|
||||
extern Class NumberClass;
|
||||
|
@ -240,6 +239,7 @@ class NestedScopeObject;
|
|||
class NewObjectCache;
|
||||
class NormalArgumentsObject;
|
||||
class NumberObject;
|
||||
class PropertyIteratorObject;
|
||||
class ScopeObject;
|
||||
class StaticBlockObject;
|
||||
class StrictArgumentsObject;
|
||||
|
@ -646,9 +646,6 @@ struct JSObject : public js::ObjectImpl
|
|||
|
||||
static const uint32_t ITER_CLASS_NFIXED_SLOTS = 1;
|
||||
|
||||
inline js::NativeIterator *getNativeIterator() const;
|
||||
inline void setNativeIterator(js::NativeIterator *);
|
||||
|
||||
/*
|
||||
* XML-related getters and setters.
|
||||
*/
|
||||
|
@ -901,9 +898,9 @@ struct JSObject : public js::ObjectImpl
|
|||
inline bool isFunction() const;
|
||||
inline bool isGenerator() const;
|
||||
inline bool isGlobal() const;
|
||||
inline bool isIterator() const;
|
||||
inline bool isObject() const;
|
||||
inline bool isPrimitive() const;
|
||||
inline bool isPropertyIterator() const;
|
||||
inline bool isProxy() const;
|
||||
inline bool isRegExp() const;
|
||||
inline bool isRegExpStatics() const;
|
||||
|
@ -957,6 +954,7 @@ struct JSObject : public js::ObjectImpl
|
|||
inline js::NestedScopeObject &asNestedScope();
|
||||
inline js::NormalArgumentsObject &asNormalArguments();
|
||||
inline js::NumberObject &asNumber();
|
||||
inline js::PropertyIteratorObject &asPropertyIterator();
|
||||
inline js::RegExpObject &asRegExp();
|
||||
inline js::ScopeObject &asScope();
|
||||
inline js::StrictArgumentsObject &asStrictArguments();
|
||||
|
|
|
@ -561,18 +561,6 @@ JSObject::setDateUTCTime(const js::Value &time)
|
|||
setFixedSlot(JSSLOT_DATE_UTC_TIME, time);
|
||||
}
|
||||
|
||||
inline js::NativeIterator *
|
||||
JSObject::getNativeIterator() const
|
||||
{
|
||||
return (js::NativeIterator *) getPrivate();
|
||||
}
|
||||
|
||||
inline void
|
||||
JSObject::setNativeIterator(js::NativeIterator *ni)
|
||||
{
|
||||
setPrivate(ni);
|
||||
}
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
|
||||
inline JSLinearString *
|
||||
|
@ -799,7 +787,6 @@ inline bool JSObject::isError() const { return hasClass(&js::ErrorClass); }
|
|||
inline bool JSObject::isFunction() const { return hasClass(&js::FunctionClass); }
|
||||
inline bool JSObject::isFunctionProxy() const { return hasClass(&js::FunctionProxyClass); }
|
||||
inline bool JSObject::isGenerator() const { return hasClass(&js::GeneratorClass); }
|
||||
inline bool JSObject::isIterator() const { return hasClass(&js::IteratorClass); }
|
||||
inline bool JSObject::isNestedScope() const { return isBlock() || isWith(); }
|
||||
inline bool JSObject::isNormalArguments() const { return hasClass(&js::NormalArgumentsObjectClass); }
|
||||
inline bool JSObject::isNumber() const { return hasClass(&js::NumberClass); }
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
#include "builtin/Iterator-inl.h"
|
||||
#include "vm/RegExpObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
|
@ -610,8 +611,8 @@ CanReify(Value *vp)
|
|||
{
|
||||
JSObject *obj;
|
||||
return vp->isObject() &&
|
||||
(obj = &vp->toObject())->getClass() == &IteratorClass &&
|
||||
(obj->getNativeIterator()->flags & JSITER_ENUMERATE);
|
||||
(obj = &vp->toObject())->isPropertyIterator() &&
|
||||
(obj->asPropertyIterator().getNativeIterator()->flags & JSITER_ENUMERATE);
|
||||
}
|
||||
|
||||
struct AutoCloseIterator
|
||||
|
@ -630,7 +631,7 @@ struct AutoCloseIterator
|
|||
static bool
|
||||
Reify(JSContext *cx, JSCompartment *origin, Value *vp)
|
||||
{
|
||||
JSObject *iterObj = &vp->toObject();
|
||||
PropertyIteratorObject *iterObj = &vp->toObject().asPropertyIterator();
|
||||
NativeIterator *ni = iterObj->getNativeIterator();
|
||||
|
||||
AutoCloseIterator close(cx, iterObj);
|
||||
|
|
|
@ -6090,7 +6090,8 @@ mjit::Compiler::iterNext(ptrdiff_t offset)
|
|||
frame.unpinReg(reg);
|
||||
|
||||
/* Test clasp */
|
||||
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, T1, &IteratorClass);
|
||||
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, T1,
|
||||
&PropertyIteratorObject::class_);
|
||||
stubcc.linkExit(notFast, Uses(1));
|
||||
|
||||
/* Get private from iter obj. */
|
||||
|
@ -6141,7 +6142,8 @@ mjit::Compiler::iterMore(jsbytecode *target)
|
|||
RegisterID tempreg = frame.allocReg();
|
||||
|
||||
/* Test clasp */
|
||||
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, tempreg, &IteratorClass);
|
||||
Jump notFast = masm.testObjClass(Assembler::NotEqual, reg, tempreg,
|
||||
&PropertyIteratorObject::class_);
|
||||
stubcc.linkExitForBranch(notFast);
|
||||
|
||||
/* Get private from iter obj. */
|
||||
|
@ -6180,7 +6182,8 @@ mjit::Compiler::iterEnd()
|
|||
frame.unpinReg(reg);
|
||||
|
||||
/* Test clasp */
|
||||
Jump notIterator = masm.testObjClass(Assembler::NotEqual, reg, T1, &IteratorClass);
|
||||
Jump notIterator = masm.testObjClass(Assembler::NotEqual, reg, T1,
|
||||
&PropertyIteratorObject::class_);
|
||||
stubcc.linkExit(notIterator, Uses(1));
|
||||
|
||||
/* Get private from iter obj. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче