js/src/jsiter.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef jsiter_h
     8 #define jsiter_h
    10 /*
    11  * JavaScript iterators.
    12  */
    14 #include "mozilla/MemoryReporting.h"
    16 #include "jscntxt.h"
    18 #include "gc/Barrier.h"
    19 #include "vm/Stack.h"
    21 /*
    22  * For cacheable native iterators, whether the iterator is currently active.
    23  * Not serialized by XDR.
    24  */
    25 #define JSITER_ACTIVE       0x1000
    26 #define JSITER_UNREUSABLE   0x2000
    28 namespace js {
    30 struct NativeIterator
    31 {
    32     HeapPtrObject obj;                  // Object being iterated.
    33     JSObject *iterObj_;                 // Internal iterator object.
    34     HeapPtr<JSFlatString> *props_array;
    35     HeapPtr<JSFlatString> *props_cursor;
    36     HeapPtr<JSFlatString> *props_end;
    37     Shape **shapes_array;
    38     uint32_t shapes_length;
    39     uint32_t shapes_key;
    40     uint32_t flags;
    42   private:
    43     /* While in compartment->enumerators, these form a doubly linked list. */
    44     NativeIterator *next_;
    45     NativeIterator *prev_;
    47   public:
    48     bool isKeyIter() const {
    49         return (flags & JSITER_FOREACH) == 0;
    50     }
    52     inline HeapPtr<JSFlatString> *begin() const {
    53         return props_array;
    54     }
    56     inline HeapPtr<JSFlatString> *end() const {
    57         return props_end;
    58     }
    60     size_t numKeys() const {
    61         return end() - begin();
    62     }
    64     JSObject *iterObj() const {
    65         return iterObj_;
    66     }
    67     HeapPtr<JSFlatString> *current() const {
    68         JS_ASSERT(props_cursor < props_end);
    69         return props_cursor;
    70     }
    72     NativeIterator *next() {
    73         return next_;
    74     }
    76     static inline size_t offsetOfNext() {
    77         return offsetof(NativeIterator, next_);
    78     }
    79     static inline size_t offsetOfPrev() {
    80         return offsetof(NativeIterator, prev_);
    81     }
    83     void incCursor() {
    84         props_cursor = props_cursor + 1;
    85     }
    86     void link(NativeIterator *other) {
    87         /* A NativeIterator cannot appear in the enumerator list twice. */
    88         JS_ASSERT(!next_ && !prev_);
    89         JS_ASSERT(flags & JSITER_ENUMERATE);
    91         this->next_ = other;
    92         this->prev_ = other->prev_;
    93         other->prev_->next_ = this;
    94         other->prev_ = this;
    95     }
    96     void unlink() {
    97         JS_ASSERT(flags & JSITER_ENUMERATE);
    99         next_->prev_ = prev_;
   100         prev_->next_ = next_;
   101         next_ = nullptr;
   102         prev_ = nullptr;
   103     }
   105     static NativeIterator *allocateSentinel(JSContext *cx);
   106     static NativeIterator *allocateIterator(JSContext *cx, uint32_t slength,
   107                                             const js::AutoIdVector &props);
   108     void init(JSObject *obj, JSObject *iterObj, unsigned flags, uint32_t slength, uint32_t key);
   110     void mark(JSTracer *trc);
   112     static void destroy(NativeIterator *iter) {
   113         js_free(iter);
   114     }
   115 };
   117 class PropertyIteratorObject : public JSObject
   118 {
   119   public:
   120     static const Class class_;
   122     NativeIterator *getNativeIterator() const {
   123         return static_cast<js::NativeIterator *>(getPrivate());
   124     }
   125     void setNativeIterator(js::NativeIterator *ni) {
   126         setPrivate(ni);
   127     }
   129     size_t sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const;
   131   private:
   132     static void trace(JSTracer *trc, JSObject *obj);
   133     static void finalize(FreeOp *fop, JSObject *obj);
   134 };
   136 class ArrayIteratorObject : public JSObject
   137 {
   138   public:
   139     static const Class class_;
   140 };
   142 class StringIteratorObject : public JSObject
   143 {
   144   public:
   145     static const Class class_;
   146 };
   148 bool
   149 VectorToIdArray(JSContext *cx, AutoIdVector &props, JSIdArray **idap);
   151 bool
   152 GetIterator(JSContext *cx, HandleObject obj, unsigned flags, MutableHandleValue vp);
   154 JSObject *
   155 GetIteratorObject(JSContext *cx, HandleObject obj, unsigned flags);
   157 bool
   158 VectorToKeyIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props,
   159                     MutableHandleValue vp);
   161 bool
   162 VectorToValueIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props,
   163                       MutableHandleValue vp);
   165 /*
   166  * Creates either a key or value iterator, depending on flags. For a value
   167  * iterator, performs value-lookup to convert the given list of jsids.
   168  */
   169 bool
   170 EnumeratedIdVectorToIterator(JSContext *cx, HandleObject obj, unsigned flags, AutoIdVector &props,
   171                              MutableHandleValue vp);
   173 /*
   174  * Convert the value stored in *vp to its iteration object. The flags should
   175  * contain JSITER_ENUMERATE if js::ValueToIterator is called when enumerating
   176  * for-in semantics are required, and when the caller can guarantee that the
   177  * iterator will never be exposed to scripts.
   178  */
   179 bool
   180 ValueToIterator(JSContext *cx, unsigned flags, MutableHandleValue vp);
   182 bool
   183 CloseIterator(JSContext *cx, HandleObject iterObj);
   185 bool
   186 UnwindIteratorForException(JSContext *cx, js::HandleObject obj);
   188 void
   189 UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj);
   191 bool
   192 IteratorConstructor(JSContext *cx, unsigned argc, Value *vp);
   194 } /* namespace js */
   196 extern bool
   197 js_SuppressDeletedProperty(JSContext *cx, js::HandleObject obj, jsid id);
   199 extern bool
   200 js_SuppressDeletedElement(JSContext *cx, js::HandleObject obj, uint32_t index);
   202 extern bool
   203 js_SuppressDeletedElements(JSContext *cx, js::HandleObject obj, uint32_t begin, uint32_t end);
   205 /*
   206  * IteratorMore() indicates whether another value is available. It might
   207  * internally call iterobj.next() and then cache the value until its
   208  * picked up by IteratorNext(). The value is cached in the current context.
   209  */
   210 extern bool
   211 js_IteratorMore(JSContext *cx, js::HandleObject iterobj, js::MutableHandleValue rval);
   213 extern bool
   214 js_IteratorNext(JSContext *cx, js::HandleObject iterobj, js::MutableHandleValue rval);
   216 extern bool
   217 js_ThrowStopIteration(JSContext *cx);
   219 namespace js {
   221 /*
   222  * Create an object of the form { value: VALUE, done: DONE }.
   223  * ES6 draft from 2013-09-05, section 25.4.3.4.
   224  */
   225 extern JSObject *
   226 CreateItrResultObject(JSContext *cx, js::HandleValue value, bool done);
   228 } /* namespace js */
   230 /*
   231  * Generator state codes.
   232  */
   233 enum JSGeneratorState
   234 {
   235     JSGEN_NEWBORN,  /* not yet started */
   236     JSGEN_OPEN,     /* started by a .next() or .send(undefined) call */
   237     JSGEN_RUNNING,  /* currently executing via .next(), etc., call */
   238     JSGEN_CLOSING,  /* close method is doing asynchronous return */
   239     JSGEN_CLOSED    /* closed, cannot be started or closed again */
   240 };
   242 struct JSGenerator
   243 {
   244     js::HeapPtrObject    obj;
   245     JSGeneratorState     state;
   246     js::InterpreterRegs  regs;
   247     JSGenerator          *prevGenerator;
   248     js::InterpreterFrame *fp;
   249     js::HeapValue        stackSnapshot[1];
   250 };
   252 extern JSObject *
   253 js_NewGenerator(JSContext *cx, const js::InterpreterRegs &regs);
   255 extern JSObject *
   256 js_InitIteratorClasses(JSContext *cx, js::HandleObject obj);
   258 #endif /* jsiter_h */

mercurial