js/src/jsapi.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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 /* JavaScript API. */
     9 #ifndef jsapi_h
    10 #define jsapi_h
    12 #include "mozilla/FloatingPoint.h"
    13 #include "mozilla/MemoryReporting.h"
    14 #include "mozilla/RangedPtr.h"
    16 #include <stdarg.h>
    17 #include <stddef.h>
    18 #include <stdint.h>
    19 #include <stdio.h>
    21 #include "jsalloc.h"
    22 #include "jspubtd.h"
    24 #include "js/CallArgs.h"
    25 #include "js/Class.h"
    26 #include "js/HashTable.h"
    27 #include "js/Id.h"
    28 #include "js/Principals.h"
    29 #include "js/RootingAPI.h"
    30 #include "js/TracingAPI.h"
    31 #include "js/Utility.h"
    32 #include "js/Value.h"
    33 #include "js/Vector.h"
    35 /************************************************************************/
    37 namespace JS {
    39 class Latin1CharsZ;
    40 class TwoByteChars;
    42 #if defined JS_THREADSAFE && defined JS_DEBUG
    44 class JS_PUBLIC_API(AutoCheckRequestDepth)
    45 {
    46     JSContext *cx;
    47   public:
    48     AutoCheckRequestDepth(JSContext *cx);
    49     AutoCheckRequestDepth(js::ContextFriendFields *cx);
    50     ~AutoCheckRequestDepth();
    51 };
    53 # define CHECK_REQUEST(cx) \
    54     JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
    56 #else
    58 # define CHECK_REQUEST(cx) \
    59     ((void) 0)
    61 #endif /* JS_THREADSAFE && JS_DEBUG */
    63 #ifdef JS_DEBUG
    64 /*
    65  * Assert that we're not doing GC on cx, that we're in a request as
    66  * needed, and that the compartments for cx and v are correct.
    67  * Also check that GC would be safe at this point.
    68  */
    69 JS_PUBLIC_API(void)
    70 AssertArgumentsAreSane(JSContext *cx, JS::HandleValue v);
    71 #else
    72 inline void AssertArgumentsAreSane(JSContext *cx, JS::HandleValue v) {
    73     /* Do nothing */
    74 }
    75 #endif /* JS_DEBUG */
    77 class JS_PUBLIC_API(AutoGCRooter) {
    78   public:
    79     AutoGCRooter(JSContext *cx, ptrdiff_t tag);
    80     AutoGCRooter(js::ContextFriendFields *cx, ptrdiff_t tag);
    82     ~AutoGCRooter() {
    83         JS_ASSERT(this == *stackTop);
    84         *stackTop = down;
    85     }
    87     /* Implemented in gc/RootMarking.cpp. */
    88     inline void trace(JSTracer *trc);
    89     static void traceAll(JSTracer *trc);
    90     static void traceAllWrappers(JSTracer *trc);
    92   protected:
    93     AutoGCRooter * const down;
    95     /*
    96      * Discriminates actual subclass of this being used.  If non-negative, the
    97      * subclass roots an array of values of the length stored in this field.
    98      * If negative, meaning is indicated by the corresponding value in the enum
    99      * below.  Any other negative value indicates some deeper problem such as
   100      * memory corruption.
   101      */
   102     ptrdiff_t tag_;
   104     enum {
   105         VALARRAY =     -2, /* js::AutoValueArray */
   106         PARSER =       -3, /* js::frontend::Parser */
   107         SHAPEVECTOR =  -4, /* js::AutoShapeVector */
   108         IDARRAY =      -6, /* js::AutoIdArray */
   109         DESCRIPTORS =  -7, /* js::AutoPropDescArrayRooter */
   110         ID =           -9, /* js::AutoIdRooter */
   111         VALVECTOR =   -10, /* js::AutoValueVector */
   112         IDVECTOR =    -13, /* js::AutoIdVector */
   113         OBJVECTOR =   -14, /* js::AutoObjectVector */
   114         STRINGVECTOR =-15, /* js::AutoStringVector */
   115         SCRIPTVECTOR =-16, /* js::AutoScriptVector */
   116         NAMEVECTOR =  -17, /* js::AutoNameVector */
   117         HASHABLEVALUE=-18, /* js::HashableValue */
   118         IONMASM =     -19, /* js::jit::MacroAssembler */
   119         IONALLOC =    -20, /* js::jit::AutoTempAllocatorRooter */
   120         WRAPVECTOR =  -21, /* js::AutoWrapperVector */
   121         WRAPPER =     -22, /* js::AutoWrapperRooter */
   122         OBJOBJHASHMAP=-23, /* js::AutoObjectObjectHashMap */
   123         OBJU32HASHMAP=-24, /* js::AutoObjectUnsigned32HashMap */
   124         OBJHASHSET =  -25, /* js::AutoObjectHashSet */
   125         JSONPARSER =  -26, /* js::JSONParser */
   126         CUSTOM =      -27, /* js::CustomAutoRooter */
   127         FUNVECTOR =   -28  /* js::AutoFunctionVector */
   128     };
   130   private:
   131     AutoGCRooter ** const stackTop;
   133     /* No copy or assignment semantics. */
   134     AutoGCRooter(AutoGCRooter &ida) MOZ_DELETE;
   135     void operator=(AutoGCRooter &ida) MOZ_DELETE;
   136 };
   138 /* AutoValueArray roots an internal fixed-size array of Values. */
   139 template <size_t N>
   140 class AutoValueArray : public AutoGCRooter
   141 {
   142     const size_t length_;
   143     Value elements_[N];
   145   public:
   146     AutoValueArray(JSContext *cx
   147                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   148       : AutoGCRooter(cx, VALARRAY), length_(N)
   149     {
   150         /* Always initialize in case we GC before assignment. */
   151         mozilla::PodArrayZero(elements_);
   152         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   153     }
   155     unsigned length() const { return length_; }
   156     const Value *begin() const { return elements_; }
   157     Value *begin() { return elements_; }
   159     HandleValue operator[](unsigned i) const {
   160         JS_ASSERT(i < N);
   161         return HandleValue::fromMarkedLocation(&elements_[i]);
   162     }
   163     MutableHandleValue operator[](unsigned i) {
   164         JS_ASSERT(i < N);
   165         return MutableHandleValue::fromMarkedLocation(&elements_[i]);
   166     }
   168     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   169 };
   171 template<class T>
   172 class AutoVectorRooter : protected AutoGCRooter
   173 {
   174     typedef js::Vector<T, 8> VectorImpl;
   175     VectorImpl vector;
   177   public:
   178     explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
   179                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   180       : AutoGCRooter(cx, tag), vector(cx)
   181     {
   182         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   183     }
   185     explicit AutoVectorRooter(js::ContextFriendFields *cx, ptrdiff_t tag
   186                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   187       : AutoGCRooter(cx, tag), vector(cx)
   188     {
   189         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   190     }
   192     typedef T ElementType;
   193     typedef typename VectorImpl::Range Range;
   195     size_t length() const { return vector.length(); }
   196     bool empty() const { return vector.empty(); }
   198     bool append(const T &v) { return vector.append(v); }
   199     bool append(const T *ptr, size_t len) { return vector.append(ptr, len); }
   200     bool appendAll(const AutoVectorRooter<T> &other) {
   201         return vector.appendAll(other.vector);
   202     }
   204     bool insert(T *p, const T &val) { return vector.insert(p, val); }
   206     /* For use when space has already been reserved. */
   207     void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
   209     void popBack() { vector.popBack(); }
   210     T popCopy() { return vector.popCopy(); }
   212     bool growBy(size_t inc) {
   213         size_t oldLength = vector.length();
   214         if (!vector.growByUninitialized(inc))
   215             return false;
   216         makeRangeGCSafe(oldLength);
   217         return true;
   218     }
   220     bool resize(size_t newLength) {
   221         size_t oldLength = vector.length();
   222         if (newLength <= oldLength) {
   223             vector.shrinkBy(oldLength - newLength);
   224             return true;
   225         }
   226         if (!vector.growByUninitialized(newLength - oldLength))
   227             return false;
   228         makeRangeGCSafe(oldLength);
   229         return true;
   230     }
   232     void clear() { vector.clear(); }
   234     bool reserve(size_t newLength) {
   235         return vector.reserve(newLength);
   236     }
   238     T &operator[](size_t i) { return vector[i]; }
   239     const T &operator[](size_t i) const { return vector[i]; }
   241     JS::MutableHandle<T> handleAt(size_t i) {
   242         return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
   243     }
   244     JS::Handle<T> handleAt(size_t i) const {
   245         return JS::Handle<T>::fromMarkedLocation(&vector[i]);
   246     }
   248     const T *begin() const { return vector.begin(); }
   249     T *begin() { return vector.begin(); }
   251     const T *end() const { return vector.end(); }
   252     T *end() { return vector.end(); }
   254     Range all() { return vector.all(); }
   256     const T &back() const { return vector.back(); }
   258     friend void AutoGCRooter::trace(JSTracer *trc);
   260   private:
   261     void makeRangeGCSafe(size_t oldLength) {
   262         T *t = vector.begin() + oldLength;
   263         for (size_t i = oldLength; i < vector.length(); ++i, ++t)
   264             memset(t, 0, sizeof(T));
   265     }
   267     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   268 };
   270 template<class Key, class Value>
   271 class AutoHashMapRooter : protected AutoGCRooter
   272 {
   273   private:
   274     typedef js::HashMap<Key, Value> HashMapImpl;
   276   public:
   277     explicit AutoHashMapRooter(JSContext *cx, ptrdiff_t tag
   278                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   279       : AutoGCRooter(cx, tag), map(cx)
   280     {
   281         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   282     }
   284     typedef Key KeyType;
   285     typedef Value ValueType;
   286     typedef typename HashMapImpl::Entry Entry;
   287     typedef typename HashMapImpl::Lookup Lookup;
   288     typedef typename HashMapImpl::Ptr Ptr;
   289     typedef typename HashMapImpl::AddPtr AddPtr;
   291     bool init(uint32_t len = 16) {
   292         return map.init(len);
   293     }
   294     bool initialized() const {
   295         return map.initialized();
   296     }
   297     Ptr lookup(const Lookup &l) const {
   298         return map.lookup(l);
   299     }
   300     void remove(Ptr p) {
   301         map.remove(p);
   302     }
   303     AddPtr lookupForAdd(const Lookup &l) const {
   304         return map.lookupForAdd(l);
   305     }
   307     template<typename KeyInput, typename ValueInput>
   308     bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) {
   309         return map.add(p, k, v);
   310     }
   312     bool add(AddPtr &p, const Key &k) {
   313         return map.add(p, k);
   314     }
   316     template<typename KeyInput, typename ValueInput>
   317     bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) {
   318         return map.relookupOrAdd(p, k, v);
   319     }
   321     typedef typename HashMapImpl::Range Range;
   322     Range all() const {
   323         return map.all();
   324     }
   326     typedef typename HashMapImpl::Enum Enum;
   328     void clear() {
   329         map.clear();
   330     }
   332     void finish() {
   333         map.finish();
   334     }
   336     bool empty() const {
   337         return map.empty();
   338     }
   340     uint32_t count() const {
   341         return map.count();
   342     }
   344     size_t capacity() const {
   345         return map.capacity();
   346     }
   348     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
   349         return map.sizeOfExcludingThis(mallocSizeOf);
   350     }
   351     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
   352         return map.sizeOfIncludingThis(mallocSizeOf);
   353     }
   355     unsigned generation() const {
   356         return map.generation();
   357     }
   359     /************************************************** Shorthand operations */
   361     bool has(const Lookup &l) const {
   362         return map.has(l);
   363     }
   365     template<typename KeyInput, typename ValueInput>
   366     bool put(const KeyInput &k, const ValueInput &v) {
   367         return map.put(k, v);
   368     }
   370     template<typename KeyInput, typename ValueInput>
   371     bool putNew(const KeyInput &k, const ValueInput &v) {
   372         return map.putNew(k, v);
   373     }
   375     Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
   376         return map.lookupWithDefault(k, defaultValue);
   377     }
   379     void remove(const Lookup &l) {
   380         map.remove(l);
   381     }
   383     friend void AutoGCRooter::trace(JSTracer *trc);
   385   private:
   386     AutoHashMapRooter(const AutoHashMapRooter &hmr) MOZ_DELETE;
   387     AutoHashMapRooter &operator=(const AutoHashMapRooter &hmr) MOZ_DELETE;
   389     HashMapImpl map;
   391     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   392 };
   394 template<class T>
   395 class AutoHashSetRooter : protected AutoGCRooter
   396 {
   397   private:
   398     typedef js::HashSet<T> HashSetImpl;
   400   public:
   401     explicit AutoHashSetRooter(JSContext *cx, ptrdiff_t tag
   402                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   403       : AutoGCRooter(cx, tag), set(cx)
   404     {
   405         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   406     }
   408     typedef typename HashSetImpl::Lookup Lookup;
   409     typedef typename HashSetImpl::Ptr Ptr;
   410     typedef typename HashSetImpl::AddPtr AddPtr;
   412     bool init(uint32_t len = 16) {
   413         return set.init(len);
   414     }
   415     bool initialized() const {
   416         return set.initialized();
   417     }
   418     Ptr lookup(const Lookup &l) const {
   419         return set.lookup(l);
   420     }
   421     void remove(Ptr p) {
   422         set.remove(p);
   423     }
   424     AddPtr lookupForAdd(const Lookup &l) const {
   425         return set.lookupForAdd(l);
   426     }
   428     bool add(AddPtr &p, const T &t) {
   429         return set.add(p, t);
   430     }
   432     bool relookupOrAdd(AddPtr &p, const Lookup &l, const T &t) {
   433         return set.relookupOrAdd(p, l, t);
   434     }
   436     typedef typename HashSetImpl::Range Range;
   437     Range all() const {
   438         return set.all();
   439     }
   441     typedef typename HashSetImpl::Enum Enum;
   443     void clear() {
   444         set.clear();
   445     }
   447     void finish() {
   448         set.finish();
   449     }
   451     bool empty() const {
   452         return set.empty();
   453     }
   455     uint32_t count() const {
   456         return set.count();
   457     }
   459     size_t capacity() const {
   460         return set.capacity();
   461     }
   463     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
   464         return set.sizeOfExcludingThis(mallocSizeOf);
   465     }
   466     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
   467         return set.sizeOfIncludingThis(mallocSizeOf);
   468     }
   470     unsigned generation() const {
   471         return set.generation();
   472     }
   474     /************************************************** Shorthand operations */
   476     bool has(const Lookup &l) const {
   477         return set.has(l);
   478     }
   480     bool put(const T &t) {
   481         return set.put(t);
   482     }
   484     bool putNew(const T &t) {
   485         return set.putNew(t);
   486     }
   488     void remove(const Lookup &l) {
   489         set.remove(l);
   490     }
   492     friend void AutoGCRooter::trace(JSTracer *trc);
   494   private:
   495     AutoHashSetRooter(const AutoHashSetRooter &hmr) MOZ_DELETE;
   496     AutoHashSetRooter &operator=(const AutoHashSetRooter &hmr) MOZ_DELETE;
   498     HashSetImpl set;
   500     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   501 };
   503 class MOZ_STACK_CLASS AutoValueVector : public AutoVectorRooter<Value>
   504 {
   505   public:
   506     explicit AutoValueVector(JSContext *cx
   507                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   508         : AutoVectorRooter<Value>(cx, VALVECTOR)
   509     {
   510         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   511     }
   513     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   514 };
   516 class AutoIdVector : public AutoVectorRooter<jsid>
   517 {
   518   public:
   519     explicit AutoIdVector(JSContext *cx
   520                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   521         : AutoVectorRooter<jsid>(cx, IDVECTOR)
   522     {
   523         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   524     }
   526     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   527 };
   529 class AutoObjectVector : public AutoVectorRooter<JSObject *>
   530 {
   531   public:
   532     explicit AutoObjectVector(JSContext *cx
   533                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   534         : AutoVectorRooter<JSObject *>(cx, OBJVECTOR)
   535     {
   536         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   537     }
   539     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   540 };
   542 class AutoFunctionVector : public AutoVectorRooter<JSFunction *>
   543 {
   544   public:
   545     explicit AutoFunctionVector(JSContext *cx
   546                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   547         : AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
   548     {
   549         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   550     }
   552     explicit AutoFunctionVector(js::ContextFriendFields *cx
   553                                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   554         : AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
   555     {
   556         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   557     }
   559     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   560 };
   562 class AutoScriptVector : public AutoVectorRooter<JSScript *>
   563 {
   564   public:
   565     explicit AutoScriptVector(JSContext *cx
   566                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   567         : AutoVectorRooter<JSScript *>(cx, SCRIPTVECTOR)
   568     {
   569         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   570     }
   572     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   573 };
   575 /*
   576  * Cutsom rooting behavior for internal and external clients.
   577  */
   578 class JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
   579 {
   580   public:
   581     template <typename CX>
   582     explicit CustomAutoRooter(CX *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   583       : AutoGCRooter(cx, CUSTOM)
   584     {
   585         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   586     }
   588     friend void AutoGCRooter::trace(JSTracer *trc);
   590   protected:
   591     /* Supplied by derived class to trace roots. */
   592     virtual void trace(JSTracer *trc) = 0;
   594   private:
   595     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   596 };
   598 /* A handle to an array of rooted values. */
   599 class HandleValueArray
   600 {
   601     const size_t length_;
   602     const Value * const elements_;
   604     HandleValueArray(size_t len, const Value *elements) : length_(len), elements_(elements) {}
   606   public:
   607     HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
   609     HandleValueArray(const AutoValueVector& values)
   610       : length_(values.length()), elements_(values.begin()) {}
   612     template <size_t N>
   613     HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
   615     /* CallArgs must already be rooted somewhere up the stack. */
   616     HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
   618     /* Use with care! Only call this if the data is guaranteed to be marked. */
   619     static HandleValueArray fromMarkedLocation(size_t len, const Value *elements) {
   620         return HandleValueArray(len, elements);
   621     }
   623     static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
   624         JS_ASSERT(startIndex + len <= values.length());
   625         return HandleValueArray(len, values.begin() + startIndex);
   626     }
   628     static HandleValueArray empty() {
   629         return HandleValueArray(0, nullptr);
   630     }
   632     size_t length() const { return length_; }
   633     const Value *begin() const { return elements_; }
   635     HandleValue operator[](size_t i) const {
   636         JS_ASSERT(i < length_);
   637         return HandleValue::fromMarkedLocation(&elements_[i]);
   638     }
   639 };
   641 }  /* namespace JS */
   643 /************************************************************************/
   645 struct JSFreeOp {
   646   private:
   647     JSRuntime   *runtime_;
   649   protected:
   650     JSFreeOp(JSRuntime *rt)
   651       : runtime_(rt) { }
   653   public:
   654     JSRuntime *runtime() const {
   655         return runtime_;
   656     }
   657 };
   659 /* Callbacks and their arguments. */
   661 /************************************************************************/
   663 typedef enum JSContextOp {
   664     JSCONTEXT_NEW,
   665     JSCONTEXT_DESTROY
   666 } JSContextOp;
   668 /*
   669  * The possible values for contextOp when the runtime calls the callback are:
   670  *   JSCONTEXT_NEW      JS_NewContext successfully created a new JSContext
   671  *                      instance. The callback can initialize the instance as
   672  *                      required. If the callback returns false, the instance
   673  *                      will be destroyed and JS_NewContext returns null. In
   674  *                      this case the callback is not called again.
   675  *   JSCONTEXT_DESTROY  One of JS_DestroyContext* methods is called. The
   676  *                      callback may perform its own cleanup and must always
   677  *                      return true.
   678  *   Any other value    For future compatibility the callback must do nothing
   679  *                      and return true in this case.
   680  */
   681 typedef bool
   682 (* JSContextCallback)(JSContext *cx, unsigned contextOp, void *data);
   684 typedef enum JSGCStatus {
   685     JSGC_BEGIN,
   686     JSGC_END
   687 } JSGCStatus;
   689 typedef void
   690 (* JSGCCallback)(JSRuntime *rt, JSGCStatus status, void *data);
   692 typedef enum JSFinalizeStatus {
   693     /*
   694      * Called when preparing to sweep a group of compartments, before anything
   695      * has been swept.  The collector will not yield to the mutator before
   696      * calling the callback with JSFINALIZE_GROUP_END status.
   697      */
   698     JSFINALIZE_GROUP_START,
   700     /*
   701      * Called when preparing to sweep a group of compartments. Weak references
   702      * to unmarked things have been removed and things that are not swept
   703      * incrementally have been finalized at this point.  The collector may yield
   704      * to the mutator after this point.
   705      */
   706     JSFINALIZE_GROUP_END,
   708     /*
   709      * Called at the end of collection when everything has been swept.
   710      */
   711     JSFINALIZE_COLLECTION_END
   712 } JSFinalizeStatus;
   714 typedef void
   715 (* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment);
   717 typedef bool
   718 (* JSInterruptCallback)(JSContext *cx);
   720 typedef void
   721 (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
   723 #ifdef MOZ_TRACE_JSCALLS
   724 typedef void
   725 (* JSFunctionCallback)(const JSFunction *fun,
   726                        const JSScript *scr,
   727                        const JSContext *cx,
   728                        int entering);
   729 #endif
   731 /*
   732  * Possible exception types. These types are part of a JSErrorFormatString
   733  * structure. They define which error to throw in case of a runtime error.
   734  * JSEXN_NONE marks an unthrowable error.
   735  */
   736 typedef enum JSExnType {
   737     JSEXN_NONE = -1,
   738       JSEXN_ERR,
   739         JSEXN_INTERNALERR,
   740         JSEXN_EVALERR,
   741         JSEXN_RANGEERR,
   742         JSEXN_REFERENCEERR,
   743         JSEXN_SYNTAXERR,
   744         JSEXN_TYPEERR,
   745         JSEXN_URIERR,
   746         JSEXN_LIMIT
   747 } JSExnType;
   749 typedef struct JSErrorFormatString {
   750     /* The error format string in ASCII. */
   751     const char *format;
   753     /* The number of arguments to expand in the formatted error message. */
   754     uint16_t argCount;
   756     /* One of the JSExnType constants above. */
   757     int16_t exnType;
   758 } JSErrorFormatString;
   760 typedef const JSErrorFormatString *
   761 (* JSErrorCallback)(void *userRef, const char *locale,
   762                     const unsigned errorNumber);
   764 typedef bool
   765 (* JSLocaleToUpperCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
   767 typedef bool
   768 (* JSLocaleToLowerCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
   770 typedef bool
   771 (* JSLocaleCompare)(JSContext *cx, JS::HandleString src1, JS::HandleString src2,
   772                     JS::MutableHandleValue rval);
   774 typedef bool
   775 (* JSLocaleToUnicode)(JSContext *cx, const char *src, JS::MutableHandleValue rval);
   777 /*
   778  * Callback used to ask the embedding for the cross compartment wrapper handler
   779  * that implements the desired prolicy for this kind of object in the
   780  * destination compartment. |obj| is the object to be wrapped. If |existing| is
   781  * non-nullptr, it will point to an existing wrapper object that should be
   782  * re-used if possible. |existing| is guaranteed to be a cross-compartment
   783  * wrapper with a lazily-defined prototype and the correct global. It is
   784  * guaranteed not to wrap a function.
   785  */
   786 typedef JSObject *
   787 (* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj,
   788                          JS::HandleObject proto, JS::HandleObject parent,
   789                          unsigned flags);
   791 /*
   792  * Callback used by the wrap hook to ask the embedding to prepare an object
   793  * for wrapping in a context. This might include unwrapping other wrappers
   794  * or even finding a more suitable object for the new compartment.
   795  */
   796 typedef JSObject *
   797 (* JSPreWrapCallback)(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj,
   798                       unsigned flags);
   800 struct JSWrapObjectCallbacks
   801 {
   802     JSWrapObjectCallback wrap;
   803     JSPreWrapCallback preWrap;
   804 };
   806 typedef void
   807 (* JSDestroyCompartmentCallback)(JSFreeOp *fop, JSCompartment *compartment);
   809 typedef void
   810 (* JSZoneCallback)(JS::Zone *zone);
   812 typedef void
   813 (* JSCompartmentNameCallback)(JSRuntime *rt, JSCompartment *compartment,
   814                               char *buf, size_t bufsize);
   816 /************************************************************************/
   818 static MOZ_ALWAYS_INLINE jsval
   819 JS_NumberValue(double d)
   820 {
   821     int32_t i;
   822     d = JS::CanonicalizeNaN(d);
   823     if (mozilla::NumberIsInt32(d, &i))
   824         return INT_TO_JSVAL(i);
   825     return DOUBLE_TO_JSVAL(d);
   826 }
   828 /************************************************************************/
   830 JS_PUBLIC_API(bool)
   831 JS_StringHasBeenInterned(JSContext *cx, JSString *str);
   833 /*
   834  * Only JSStrings that have been interned via the JSAPI can be turned into
   835  * jsids by API clients.
   836  *
   837  * N.B. if a jsid is backed by a string which has not been interned, that
   838  * string must be appropriately rooted to avoid being collected by the GC.
   839  */
   840 JS_PUBLIC_API(jsid)
   841 INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str);
   843 /*
   844  * Returns true iff the given jsval is immune to GC and can be used across
   845  * multiple JSRuntimes without requiring any conversion API.
   846  */
   847 static MOZ_ALWAYS_INLINE bool
   848 JSVAL_IS_UNIVERSAL(jsval v)
   849 {
   850     return !JSVAL_IS_GCTHING(v);
   851 }
   853 namespace JS {
   855 class AutoIdRooter : private AutoGCRooter
   856 {
   857   public:
   858     explicit AutoIdRooter(JSContext *cx, jsid aId = INT_TO_JSID(0)
   859                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
   860       : AutoGCRooter(cx, ID), id_(aId)
   861     {
   862         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   863     }
   865     jsid id() {
   866         return id_;
   867     }
   869     jsid * addr() {
   870         return &id_;
   871     }
   873     friend void AutoGCRooter::trace(JSTracer *trc);
   875   private:
   876     jsid id_;
   877     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   878 };
   880 // Container class for passing in script source buffers to the JS engine.  This
   881 // not only groups the buffer and length values, it also provides a way to
   882 // optionally pass ownership of the buffer to the JS engine without copying.
   883 // Rules for use:
   884 //
   885 //  1) The data array must be allocated with js_malloc() or js_realloc() if
   886 //     ownership is being granted to the SourceBufferHolder.
   887 //  2) If ownership is not given to the SourceBufferHolder, then the memory
   888 //     must be kept alive until the JS compilation is complete.
   889 //  3) Any code calling SourceBufferHolder::take() must guarantee to keep the
   890 //     memory alive until JS compilation completes.  Normally only the JS
   891 //     engine should be calling take().
   892 //
   893 // Example use:
   894 //
   895 //    size_t length = 512;
   896 //    jschar* chars = static_cast<jschar*>(js_malloc(sizeof(jschar) * length));
   897 //    JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
   898 //    JS::Compile(cx, obj, options, srcBuf);
   899 //
   900 class MOZ_STACK_CLASS SourceBufferHolder MOZ_FINAL
   901 {
   902   public:
   903     enum Ownership {
   904       NoOwnership,
   905       GiveOwnership
   906     };
   908     SourceBufferHolder(const jschar *data, size_t dataLength, Ownership ownership)
   909       : data_(data),
   910         length_(dataLength),
   911         ownsChars_(ownership == GiveOwnership)
   912     {
   913         // Ensure that null buffers properly return an unowned, empty,
   914         // null-terminated string.
   915         static const jschar NullChar_ = 0;
   916         if (!get()) {
   917             data_ = &NullChar_;
   918             length_ = 0;
   919             ownsChars_ = false;
   920         }
   921     }
   923     ~SourceBufferHolder() {
   924         if (ownsChars_)
   925             js_free(const_cast<jschar *>(data_));
   926     }
   928     // Access the underlying source buffer without affecting ownership.
   929     const jschar *get() const { return data_; }
   931     // Length of the source buffer in jschars (not bytes)
   932     size_t length() const { return length_; }
   934     // Returns true if the SourceBufferHolder owns the buffer and will free
   935     // it upon destruction.  If true, it is legal to call take().
   936     bool ownsChars() const { return ownsChars_; }
   938     // Retrieve and take ownership of the underlying data buffer.  The caller
   939     // is now responsible for calling js_free() on the returned value, *but only
   940     // after JS script compilation has completed*.
   941     //
   942     // After the buffer has been taken the SourceBufferHolder functions as if
   943     // it had been constructed on an unowned buffer;  get() and length() still
   944     // work.  In order for this to be safe the taken buffer must be kept alive
   945     // until after JS script compilation completes as noted above.
   946     //
   947     // Note, it's the caller's responsibility to check ownsChars() before taking
   948     // the buffer.  Taking and then free'ing an unowned buffer will have dire
   949     // consequences.
   950     jschar *take() {
   951         JS_ASSERT(ownsChars_);
   952         ownsChars_ = false;
   953         return const_cast<jschar *>(data_);
   954     }
   956   private:
   957     SourceBufferHolder(SourceBufferHolder &) MOZ_DELETE;
   958     SourceBufferHolder &operator=(SourceBufferHolder &) MOZ_DELETE;
   960     const jschar *data_;
   961     size_t length_;
   962     bool ownsChars_;
   963 };
   965 } /* namespace JS */
   967 /************************************************************************/
   969 /* Property attributes, set in JSPropertySpec and passed to API functions. */
   970 #define JSPROP_ENUMERATE        0x01    /* property is visible to for/in loop */
   971 #define JSPROP_READONLY         0x02    /* not settable: assignment is no-op.
   972                                            This flag is only valid when neither
   973                                            JSPROP_GETTER nor JSPROP_SETTER is
   974                                            set. */
   975 #define JSPROP_PERMANENT        0x04    /* property cannot be deleted */
   976 #define JSPROP_NATIVE_ACCESSORS 0x08    /* set in JSPropertyDescriptor.flags
   977                                            if getters/setters are JSNatives */
   978 #define JSPROP_GETTER           0x10    /* property holds getter function */
   979 #define JSPROP_SETTER           0x20    /* property holds setter function */
   980 #define JSPROP_SHARED           0x40    /* don't allocate a value slot for this
   981                                            property; don't copy the property on
   982                                            set of the same-named property in an
   983                                            object that delegates to a prototype
   984                                            containing this property */
   985 #define JSPROP_INDEX            0x80    /* name is actually (int) index */
   987 #define JSFUN_STUB_GSOPS       0x200    /* use JS_PropertyStub getter/setter
   988                                            instead of defaulting to class gsops
   989                                            for property holding function */
   991 #define JSFUN_CONSTRUCTOR      0x400    /* native that can be called as a ctor */
   994 /*
   995  * Specify a generic native prototype methods, i.e., methods of a class
   996  * prototype that are exposed as static methods taking an extra leading
   997  * argument: the generic |this| parameter.
   998  *
   999  * If you set this flag in a JSFunctionSpec struct's flags initializer, then
  1000  * that struct must live at least as long as the native static method object
  1001  * created due to this flag by JS_DefineFunctions or JS_InitClass.  Typically
  1002  * JSFunctionSpec structs are allocated in static arrays.
  1003  */
  1004 #define JSFUN_GENERIC_NATIVE   0x800
  1006 #define JSFUN_FLAGS_MASK       0xe00    /* | of all the JSFUN_* flags */
  1008 /*
  1009  * The first call to JS_CallOnce by any thread in a process will call 'func'.
  1010  * Later calls to JS_CallOnce with the same JSCallOnceType object will be
  1011  * suppressed.
  1013  * Equivalently: each distinct JSCallOnceType object will allow one JS_CallOnce
  1014  * to invoke its JSInitCallback.
  1015  */
  1016 extern JS_PUBLIC_API(bool)
  1017 JS_CallOnce(JSCallOnceType *once, JSInitCallback func);
  1019 /* Microseconds since the epoch, midnight, January 1, 1970 UTC. */
  1020 extern JS_PUBLIC_API(int64_t)
  1021 JS_Now(void);
  1023 /* Don't want to export data, so provide accessors for non-inline jsvals. */
  1024 extern JS_PUBLIC_API(jsval)
  1025 JS_GetNaNValue(JSContext *cx);
  1027 extern JS_PUBLIC_API(jsval)
  1028 JS_GetNegativeInfinityValue(JSContext *cx);
  1030 extern JS_PUBLIC_API(jsval)
  1031 JS_GetPositiveInfinityValue(JSContext *cx);
  1033 extern JS_PUBLIC_API(jsval)
  1034 JS_GetEmptyStringValue(JSContext *cx);
  1036 extern JS_PUBLIC_API(JSString *)
  1037 JS_GetEmptyString(JSRuntime *rt);
  1039 /*
  1040  * Format is a string of the following characters (spaces are insignificant),
  1041  * specifying the tabulated type conversions:
  1043  *   b      bool            Boolean
  1044  *   c      uint16_t/jschar ECMA uint16_t, Unicode char
  1045  *   i      int32_t         ECMA int32_t
  1046  *   j      int32_t         ECMA int32_t (used to be different)
  1047  *   u      uint32_t        ECMA uint32_t
  1048  *   d      double          IEEE double
  1049  *   I      double          Integral IEEE double
  1050  *   S      JSString *      Unicode string, accessed by a JSString pointer
  1051  *   W      jschar *        Unicode character vector, 0-terminated (W for wide)
  1052  *   o      JSObject *      Object reference
  1053  *   f      JSFunction *    Function private
  1054  *   v      jsval           Argument value (no conversion)
  1055  *   *      N/A             Skip this argument (no vararg)
  1056  *   /      N/A             End of required arguments
  1058  * The variable argument list after format must consist of &b, &c, &s, e.g.,
  1059  * where those variables have the types given above.  For the pointer types
  1060  * char *, JSString *, and JSObject *, the pointed-at memory returned belongs
  1061  * to the JS runtime, not to the calling native code.  The runtime promises
  1062  * to keep this memory valid so long as argv refers to allocated stack space
  1063  * (so long as the native function is active).
  1065  * Fewer arguments than format specifies may be passed only if there is a /
  1066  * in format after the last required argument specifier and argc is at least
  1067  * the number of required arguments.  More arguments than format specifies
  1068  * may be passed without error; it is up to the caller to deal with trailing
  1069  * unconverted arguments.
  1070  */
  1071 extern JS_PUBLIC_API(bool)
  1072 JS_ConvertArguments(JSContext *cx, const JS::CallArgs &args, const char *format, ...);
  1074 #ifdef va_start
  1075 extern JS_PUBLIC_API(bool)
  1076 JS_ConvertArgumentsVA(JSContext *cx, const JS::CallArgs &args, const char *format,
  1077                       va_list ap);
  1078 #endif
  1080 extern JS_PUBLIC_API(bool)
  1081 JS_ConvertValue(JSContext *cx, JS::HandleValue v, JSType type, JS::MutableHandleValue vp);
  1083 extern JS_PUBLIC_API(bool)
  1084 JS_ValueToObject(JSContext *cx, JS::HandleValue v, JS::MutableHandleObject objp);
  1086 extern JS_PUBLIC_API(JSFunction *)
  1087 JS_ValueToFunction(JSContext *cx, JS::HandleValue v);
  1089 extern JS_PUBLIC_API(JSFunction *)
  1090 JS_ValueToConstructor(JSContext *cx, JS::HandleValue v);
  1092 extern JS_PUBLIC_API(JSString *)
  1093 JS_ValueToSource(JSContext *cx, JS::Handle<JS::Value> v);
  1095 namespace js {
  1096 /*
  1097  * DO NOT CALL THIS.  Use JS::ToNumber
  1098  */
  1099 extern JS_PUBLIC_API(bool)
  1100 ToNumberSlow(JSContext *cx, JS::Value v, double *dp);
  1102 /*
  1103  * DO NOT CALL THIS. Use JS::ToBoolean
  1104  */
  1105 extern JS_PUBLIC_API(bool)
  1106 ToBooleanSlow(JS::HandleValue v);
  1108 /*
  1109  * DO NOT CALL THIS. Use JS::ToString
  1110  */
  1111 extern JS_PUBLIC_API(JSString*)
  1112 ToStringSlow(JSContext *cx, JS::HandleValue v);
  1113 } /* namespace js */
  1115 namespace JS {
  1117 /* ES5 9.3 ToNumber. */
  1118 MOZ_ALWAYS_INLINE bool
  1119 ToNumber(JSContext *cx, HandleValue v, double *out)
  1121     AssertArgumentsAreSane(cx, v);
  1123     if (v.isNumber()) {
  1124         *out = v.toNumber();
  1125         return true;
  1127     return js::ToNumberSlow(cx, v, out);
  1130 MOZ_ALWAYS_INLINE bool
  1131 ToBoolean(HandleValue v)
  1133     if (v.isBoolean())
  1134         return v.toBoolean();
  1135     if (v.isInt32())
  1136         return v.toInt32() != 0;
  1137     if (v.isNullOrUndefined())
  1138         return false;
  1139     if (v.isDouble()) {
  1140         double d = v.toDouble();
  1141         return !mozilla::IsNaN(d) && d != 0;
  1144     /* The slow path handles strings and objects. */
  1145     return js::ToBooleanSlow(v);
  1148 MOZ_ALWAYS_INLINE JSString*
  1149 ToString(JSContext *cx, HandleValue v)
  1151     if (v.isString())
  1152         return v.toString();
  1153     return js::ToStringSlow(cx, v);
  1156 } /* namespace JS */
  1158 extern JS_PUBLIC_API(bool)
  1159 JS_DoubleIsInt32(double d, int32_t *ip);
  1161 extern JS_PUBLIC_API(int32_t)
  1162 JS_DoubleToInt32(double d);
  1164 extern JS_PUBLIC_API(uint32_t)
  1165 JS_DoubleToUint32(double d);
  1168 namespace js {
  1169 /* DO NOT CALL THIS. Use JS::ToUint16. */
  1170 extern JS_PUBLIC_API(bool)
  1171 ToUint16Slow(JSContext *cx, JS::HandleValue v, uint16_t *out);
  1173 /* DO NOT CALL THIS. Use JS::ToInt32. */
  1174 extern JS_PUBLIC_API(bool)
  1175 ToInt32Slow(JSContext *cx, JS::HandleValue v, int32_t *out);
  1177 /* DO NOT CALL THIS. Use JS::ToUint32. */
  1178 extern JS_PUBLIC_API(bool)
  1179 ToUint32Slow(JSContext *cx, JS::HandleValue v, uint32_t *out);
  1181 /* DO NOT CALL THIS. Use JS::ToInt64. */
  1182 extern JS_PUBLIC_API(bool)
  1183 ToInt64Slow(JSContext *cx, JS::HandleValue v, int64_t *out);
  1185 /* DO NOT CALL THIS. Use JS::ToUint64. */
  1186 extern JS_PUBLIC_API(bool)
  1187 ToUint64Slow(JSContext *cx, JS::HandleValue v, uint64_t *out);
  1188 } /* namespace js */
  1190 namespace JS {
  1192 MOZ_ALWAYS_INLINE bool
  1193 ToUint16(JSContext *cx, JS::HandleValue v, uint16_t *out)
  1195     AssertArgumentsAreSane(cx, v);
  1197     if (v.isInt32()) {
  1198         *out = uint16_t(v.toInt32());
  1199         return true;
  1201     return js::ToUint16Slow(cx, v, out);
  1204 MOZ_ALWAYS_INLINE bool
  1205 ToInt32(JSContext *cx, JS::HandleValue v, int32_t *out)
  1207     AssertArgumentsAreSane(cx, v);
  1209     if (v.isInt32()) {
  1210         *out = v.toInt32();
  1211         return true;
  1213     return js::ToInt32Slow(cx, v, out);
  1216 MOZ_ALWAYS_INLINE bool
  1217 ToUint32(JSContext *cx, JS::HandleValue v, uint32_t *out)
  1219     AssertArgumentsAreSane(cx, v);
  1221     if (v.isInt32()) {
  1222         *out = uint32_t(v.toInt32());
  1223         return true;
  1225     return js::ToUint32Slow(cx, v, out);
  1228 MOZ_ALWAYS_INLINE bool
  1229 ToInt64(JSContext *cx, JS::HandleValue v, int64_t *out)
  1231     AssertArgumentsAreSane(cx, v);
  1233     if (v.isInt32()) {
  1234         *out = int64_t(v.toInt32());
  1235         return true;
  1237     return js::ToInt64Slow(cx, v, out);
  1240 MOZ_ALWAYS_INLINE bool
  1241 ToUint64(JSContext *cx, JS::HandleValue v, uint64_t *out)
  1243     AssertArgumentsAreSane(cx, v);
  1245     if (v.isInt32()) {
  1246         /* Account for sign extension of negatives into the longer 64bit space. */
  1247         *out = uint64_t(int64_t(v.toInt32()));
  1248         return true;
  1250     return js::ToUint64Slow(cx, v, out);
  1254 } /* namespace JS */
  1256 extern JS_PUBLIC_API(JSType)
  1257 JS_TypeOfValue(JSContext *cx, JS::Handle<JS::Value> v);
  1259 extern JS_PUBLIC_API(const char *)
  1260 JS_GetTypeName(JSContext *cx, JSType type);
  1262 extern JS_PUBLIC_API(bool)
  1263 JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, bool *equal);
  1265 extern JS_PUBLIC_API(bool)
  1266 JS_LooselyEqual(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *equal);
  1268 extern JS_PUBLIC_API(bool)
  1269 JS_SameValue(JSContext *cx, jsval v1, jsval v2, bool *same);
  1271 /* True iff fun is the global eval function. */
  1272 extern JS_PUBLIC_API(bool)
  1273 JS_IsBuiltinEvalFunction(JSFunction *fun);
  1275 /* True iff fun is the Function constructor. */
  1276 extern JS_PUBLIC_API(bool)
  1277 JS_IsBuiltinFunctionConstructor(JSFunction *fun);
  1279 /************************************************************************/
  1281 /*
  1282  * Initialization, locking, contexts, and memory allocation.
  1284  * It is important that the first runtime and first context be created in a
  1285  * single-threaded fashion, otherwise the behavior of the library is undefined.
  1286  * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
  1287  */
  1289 typedef enum JSUseHelperThreads
  1291     JS_NO_HELPER_THREADS,
  1292     JS_USE_HELPER_THREADS
  1293 } JSUseHelperThreads;
  1295 /**
  1296  * Initialize SpiderMonkey, returning true only if initialization succeeded.
  1297  * Once this method has succeeded, it is safe to call JS_NewRuntime and other
  1298  * JSAPI methods.
  1300  * This method must be called before any other JSAPI method is used on any
  1301  * thread.  Once it has been used, it is safe to call any JSAPI method, and it
  1302  * remains safe to do so until JS_ShutDown is correctly called.
  1304  * It is currently not possible to initialize SpiderMonkey multiple times (that
  1305  * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
  1306  * again).  This restriction may eventually be lifted.
  1307  */
  1308 extern JS_PUBLIC_API(bool)
  1309 JS_Init(void);
  1311 /**
  1312  * Destroy free-standing resources allocated by SpiderMonkey, not associated
  1313  * with any runtime, context, or other structure.
  1315  * This method should be called after all other JSAPI data has been properly
  1316  * cleaned up: every new runtime must have been destroyed, every new context
  1317  * must have been destroyed, and so on.  Calling this method before all other
  1318  * resources have been destroyed has undefined behavior.
  1320  * Failure to call this method, at present, has no adverse effects other than
  1321  * leaking memory.  This may not always be the case; it's recommended that all
  1322  * embedders call this method when all other JSAPI operations have completed.
  1324  * It is currently not possible to initialize SpiderMonkey multiple times (that
  1325  * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
  1326  * again).  This restriction may eventually be lifted.
  1327  */
  1328 extern JS_PUBLIC_API(void)
  1329 JS_ShutDown(void);
  1331 extern JS_PUBLIC_API(JSRuntime *)
  1332 JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads,
  1333               JSRuntime *parentRuntime = nullptr);
  1335 extern JS_PUBLIC_API(void)
  1336 JS_DestroyRuntime(JSRuntime *rt);
  1338 // These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and
  1339 // |UMemFreeFn| types.  The first argument (called |context| in the ICU docs)
  1340 // will always be nullptr, and should be ignored.
  1341 typedef void *(*JS_ICUAllocFn)(const void *, size_t size);
  1342 typedef void *(*JS_ICUReallocFn)(const void *, void *p, size_t size);
  1343 typedef void (*JS_ICUFreeFn)(const void *, void *p);
  1345 // This function can be used to track memory used by ICU.
  1346 // Do not use it unless you know what you are doing!
  1347 extern JS_PUBLIC_API(bool)
  1348 JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, JS_ICUReallocFn reallocFn, JS_ICUFreeFn freeFn);
  1350 JS_PUBLIC_API(void *)
  1351 JS_GetRuntimePrivate(JSRuntime *rt);
  1353 extern JS_PUBLIC_API(JSRuntime *)
  1354 JS_GetRuntime(JSContext *cx);
  1356 extern JS_PUBLIC_API(JSRuntime *)
  1357 JS_GetParentRuntime(JSContext *cx);
  1359 JS_PUBLIC_API(void)
  1360 JS_SetRuntimePrivate(JSRuntime *rt, void *data);
  1362 extern JS_PUBLIC_API(void)
  1363 JS_BeginRequest(JSContext *cx);
  1365 extern JS_PUBLIC_API(void)
  1366 JS_EndRequest(JSContext *cx);
  1368 extern JS_PUBLIC_API(bool)
  1369 JS_IsInRequest(JSRuntime *rt);
  1371 namespace js {
  1373 void
  1374 AssertHeapIsIdle(JSRuntime *rt);
  1376 void
  1377 AssertHeapIsIdle(JSContext *cx);
  1379 } /* namespace js */
  1381 class JSAutoRequest
  1383   public:
  1384     JSAutoRequest(JSContext *cx
  1385                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  1386       : mContext(cx)
  1388         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  1389         JS_BeginRequest(mContext);
  1391     ~JSAutoRequest() {
  1392         JS_EndRequest(mContext);
  1395   protected:
  1396     JSContext *mContext;
  1397     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  1399 #if 0
  1400   private:
  1401     static void *operator new(size_t) CPP_THROW_NEW { return 0; };
  1402     static void operator delete(void *, size_t) { };
  1403 #endif
  1404 };
  1406 class JSAutoCheckRequest
  1408   public:
  1409     JSAutoCheckRequest(JSContext *cx
  1410                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  1412 #if defined JS_THREADSAFE && defined JS_DEBUG
  1413         mContext = cx;
  1414         JS_ASSERT(JS_IsInRequest(JS_GetRuntime(cx)));
  1415 #endif
  1416         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  1419     ~JSAutoCheckRequest() {
  1420 #if defined JS_THREADSAFE && defined JS_DEBUG
  1421         JS_ASSERT(JS_IsInRequest(JS_GetRuntime(mContext)));
  1422 #endif
  1426   private:
  1427 #if defined JS_THREADSAFE && defined JS_DEBUG
  1428     JSContext *mContext;
  1429 #endif
  1430     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  1431 };
  1433 extern JS_PUBLIC_API(void)
  1434 JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback, void *data);
  1436 extern JS_PUBLIC_API(JSContext *)
  1437 JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
  1439 extern JS_PUBLIC_API(void)
  1440 JS_DestroyContext(JSContext *cx);
  1442 extern JS_PUBLIC_API(void)
  1443 JS_DestroyContextNoGC(JSContext *cx);
  1445 extern JS_PUBLIC_API(void *)
  1446 JS_GetContextPrivate(JSContext *cx);
  1448 extern JS_PUBLIC_API(void)
  1449 JS_SetContextPrivate(JSContext *cx, void *data);
  1451 extern JS_PUBLIC_API(void *)
  1452 JS_GetSecondContextPrivate(JSContext *cx);
  1454 extern JS_PUBLIC_API(void)
  1455 JS_SetSecondContextPrivate(JSContext *cx, void *data);
  1457 extern JS_PUBLIC_API(JSRuntime *)
  1458 JS_GetRuntime(JSContext *cx);
  1460 extern JS_PUBLIC_API(JSContext *)
  1461 JS_ContextIterator(JSRuntime *rt, JSContext **iterp);
  1463 extern JS_PUBLIC_API(JSVersion)
  1464 JS_GetVersion(JSContext *cx);
  1466 // Mutate the version on the compartment. This is generally discouraged, but
  1467 // necessary to support the version mutation in the js and xpc shell command
  1468 // set.
  1469 //
  1470 // It would be nice to put this in jsfriendapi, but the linkage requirements
  1471 // of the shells make that impossible.
  1472 JS_PUBLIC_API(void)
  1473 JS_SetVersionForCompartment(JSCompartment *compartment, JSVersion version);
  1475 extern JS_PUBLIC_API(const char *)
  1476 JS_VersionToString(JSVersion version);
  1478 extern JS_PUBLIC_API(JSVersion)
  1479 JS_StringToVersion(const char *string);
  1481 namespace JS {
  1483 class JS_PUBLIC_API(RuntimeOptions) {
  1484   public:
  1485     RuntimeOptions()
  1486       : baseline_(false),
  1487         ion_(false),
  1488         asmJS_(false)
  1492     bool baseline() const { return baseline_; }
  1493     RuntimeOptions &setBaseline(bool flag) {
  1494         baseline_ = flag;
  1495         return *this;
  1497     RuntimeOptions &toggleBaseline() {
  1498         baseline_ = !baseline_;
  1499         return *this;
  1502     bool ion() const { return ion_; }
  1503     RuntimeOptions &setIon(bool flag) {
  1504         ion_ = flag;
  1505         return *this;
  1507     RuntimeOptions &toggleIon() {
  1508         ion_ = !ion_;
  1509         return *this;
  1512     bool asmJS() const { return asmJS_; }
  1513     RuntimeOptions &setAsmJS(bool flag) {
  1514         asmJS_ = flag;
  1515         return *this;
  1517     RuntimeOptions &toggleAsmJS() {
  1518         asmJS_ = !asmJS_;
  1519         return *this;
  1522   private:
  1523     bool baseline_ : 1;
  1524     bool ion_ : 1;
  1525     bool asmJS_ : 1;
  1526 };
  1528 JS_PUBLIC_API(RuntimeOptions &)
  1529 RuntimeOptionsRef(JSRuntime *rt);
  1531 JS_PUBLIC_API(RuntimeOptions &)
  1532 RuntimeOptionsRef(JSContext *cx);
  1534 class JS_PUBLIC_API(ContextOptions) {
  1535   public:
  1536     ContextOptions()
  1537       : extraWarnings_(false),
  1538         werror_(false),
  1539         varObjFix_(false),
  1540         privateIsNSISupports_(false),
  1541         dontReportUncaught_(false),
  1542         noDefaultCompartmentObject_(false),
  1543         noScriptRval_(false),
  1544         strictMode_(false),
  1545         cloneSingletons_(false)
  1549     bool extraWarnings() const { return extraWarnings_; }
  1550     ContextOptions &setExtraWarnings(bool flag) {
  1551         extraWarnings_ = flag;
  1552         return *this;
  1554     ContextOptions &toggleExtraWarnings() {
  1555         extraWarnings_ = !extraWarnings_;
  1556         return *this;
  1559     bool werror() const { return werror_; }
  1560     ContextOptions &setWerror(bool flag) {
  1561         werror_ = flag;
  1562         return *this;
  1564     ContextOptions &toggleWerror() {
  1565         werror_ = !werror_;
  1566         return *this;
  1569     bool varObjFix() const { return varObjFix_; }
  1570     ContextOptions &setVarObjFix(bool flag) {
  1571         varObjFix_ = flag;
  1572         return *this;
  1574     ContextOptions &toggleVarObjFix() {
  1575         varObjFix_ = !varObjFix_;
  1576         return *this;
  1579     bool privateIsNSISupports() const { return privateIsNSISupports_; }
  1580     ContextOptions &setPrivateIsNSISupports(bool flag) {
  1581         privateIsNSISupports_ = flag;
  1582         return *this;
  1584     ContextOptions &togglePrivateIsNSISupports() {
  1585         privateIsNSISupports_ = !privateIsNSISupports_;
  1586         return *this;
  1589     bool dontReportUncaught() const { return dontReportUncaught_; }
  1590     ContextOptions &setDontReportUncaught(bool flag) {
  1591         dontReportUncaught_ = flag;
  1592         return *this;
  1594     ContextOptions &toggleDontReportUncaught() {
  1595         dontReportUncaught_ = !dontReportUncaught_;
  1596         return *this;
  1599     bool noDefaultCompartmentObject() const { return noDefaultCompartmentObject_; }
  1600     ContextOptions &setNoDefaultCompartmentObject(bool flag) {
  1601         noDefaultCompartmentObject_ = flag;
  1602         return *this;
  1604     ContextOptions &toggleNoDefaultCompartmentObject() {
  1605         noDefaultCompartmentObject_ = !noDefaultCompartmentObject_;
  1606         return *this;
  1609     bool noScriptRval() const { return noScriptRval_; }
  1610     ContextOptions &setNoScriptRval(bool flag) {
  1611         noScriptRval_ = flag;
  1612         return *this;
  1614     ContextOptions &toggleNoScriptRval() {
  1615         noScriptRval_ = !noScriptRval_;
  1616         return *this;
  1619     bool strictMode() const { return strictMode_; }
  1620     ContextOptions &setStrictMode(bool flag) {
  1621         strictMode_ = flag;
  1622         return *this;
  1624     ContextOptions &toggleStrictMode() {
  1625         strictMode_ = !strictMode_;
  1626         return *this;
  1629     bool cloneSingletons() const { return cloneSingletons_; }
  1630     ContextOptions &setCloneSingletons(bool flag) {
  1631         cloneSingletons_ = flag;
  1632         return *this;
  1634     ContextOptions &toggleCloneSingletons() {
  1635         cloneSingletons_ = !cloneSingletons_;
  1636         return *this;
  1639   private:
  1640     bool extraWarnings_ : 1;
  1641     bool werror_ : 1;
  1642     bool varObjFix_ : 1;
  1643     bool privateIsNSISupports_ : 1;
  1644     bool dontReportUncaught_ : 1;
  1645     bool noDefaultCompartmentObject_ : 1;
  1646     bool noScriptRval_ : 1;
  1647     bool strictMode_ : 1;
  1648     bool cloneSingletons_ : 1;
  1649 };
  1651 JS_PUBLIC_API(ContextOptions &)
  1652 ContextOptionsRef(JSContext *cx);
  1654 class JS_PUBLIC_API(AutoSaveContextOptions) {
  1655   public:
  1656     AutoSaveContextOptions(JSContext *cx)
  1657       : cx_(cx),
  1658         oldOptions_(ContextOptionsRef(cx_))
  1662     ~AutoSaveContextOptions()
  1664         ContextOptionsRef(cx_) = oldOptions_;
  1667   private:
  1668     JSContext *cx_;
  1669     JS::ContextOptions oldOptions_;
  1670 };
  1672 } /* namespace JS */
  1674 extern JS_PUBLIC_API(const char *)
  1675 JS_GetImplementationVersion(void);
  1677 extern JS_PUBLIC_API(void)
  1678 JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback callback);
  1680 extern JS_PUBLIC_API(void)
  1681 JS_SetDestroyZoneCallback(JSRuntime *rt, JSZoneCallback callback);
  1683 extern JS_PUBLIC_API(void)
  1684 JS_SetSweepZoneCallback(JSRuntime *rt, JSZoneCallback callback);
  1686 extern JS_PUBLIC_API(void)
  1687 JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback);
  1689 extern JS_PUBLIC_API(void)
  1690 JS_SetWrapObjectCallbacks(JSRuntime *rt, const JSWrapObjectCallbacks *callbacks);
  1692 extern JS_PUBLIC_API(void)
  1693 JS_SetCompartmentPrivate(JSCompartment *compartment, void *data);
  1695 extern JS_PUBLIC_API(void *)
  1696 JS_GetCompartmentPrivate(JSCompartment *compartment);
  1698 extern JS_PUBLIC_API(void)
  1699 JS_SetZoneUserData(JS::Zone *zone, void *data);
  1701 extern JS_PUBLIC_API(void *)
  1702 JS_GetZoneUserData(JS::Zone *zone);
  1704 extern JS_PUBLIC_API(bool)
  1705 JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
  1707 extern JS_PUBLIC_API(bool)
  1708 JS_WrapValue(JSContext *cx, JS::MutableHandleValue vp);
  1710 extern JS_PUBLIC_API(bool)
  1711 JS_WrapId(JSContext *cx, JS::MutableHandleId idp);
  1713 extern JS_PUBLIC_API(JSObject *)
  1714 JS_TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject target);
  1716 extern JS_PUBLIC_API(bool)
  1717 JS_RefreshCrossCompartmentWrappers(JSContext *cx, JS::Handle<JSObject*> obj);
  1719 /*
  1720  * At any time, a JSContext has a current (possibly-nullptr) compartment.
  1721  * Compartments are described in:
  1723  *   developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
  1725  * The current compartment of a context may be changed. The preferred way to do
  1726  * this is with JSAutoCompartment:
  1728  *   void foo(JSContext *cx, JSObject *obj) {
  1729  *     // in some compartment 'c'
  1730  *     {
  1731  *       JSAutoCompartment ac(cx, obj);  // constructor enters
  1732  *       // in the compartment of 'obj'
  1733  *     }                                 // destructor leaves
  1734  *     // back in compartment 'c'
  1735  *   }
  1737  * For more complicated uses that don't neatly fit in a C++ stack frame, the
  1738  * compartment can entered and left using separate function calls:
  1740  *   void foo(JSContext *cx, JSObject *obj) {
  1741  *     // in 'oldCompartment'
  1742  *     JSCompartment *oldCompartment = JS_EnterCompartment(cx, obj);
  1743  *     // in the compartment of 'obj'
  1744  *     JS_LeaveCompartment(cx, oldCompartment);
  1745  *     // back in 'oldCompartment'
  1746  *   }
  1748  * Note: these calls must still execute in a LIFO manner w.r.t all other
  1749  * enter/leave calls on the context. Furthermore, only the return value of a
  1750  * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
  1751  * the corresponding JS_LeaveCompartment call.
  1752  */
  1754 class JS_PUBLIC_API(JSAutoCompartment)
  1756     JSContext *cx_;
  1757     JSCompartment *oldCompartment_;
  1758   public:
  1759     JSAutoCompartment(JSContext *cx, JSObject *target);
  1760     JSAutoCompartment(JSContext *cx, JSScript *target);
  1761     ~JSAutoCompartment();
  1762 };
  1764 class JS_PUBLIC_API(JSAutoNullCompartment)
  1766     JSContext *cx_;
  1767     JSCompartment *oldCompartment_;
  1768   public:
  1769     JSAutoNullCompartment(JSContext *cx);
  1770     ~JSAutoNullCompartment();
  1771 };
  1773 /* NB: This API is infallible; a nullptr return value does not indicate error. */
  1774 extern JS_PUBLIC_API(JSCompartment *)
  1775 JS_EnterCompartment(JSContext *cx, JSObject *target);
  1777 extern JS_PUBLIC_API(void)
  1778 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment);
  1780 typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);
  1782 /*
  1783  * This function calls |compartmentCallback| on every compartment.  Beware that
  1784  * there is no guarantee that the compartment will survive after the callback
  1785  * returns.
  1786  */
  1787 extern JS_PUBLIC_API(void)
  1788 JS_IterateCompartments(JSRuntime *rt, void *data,
  1789                        JSIterateCompartmentCallback compartmentCallback);
  1791 /*
  1792  * Initialize standard JS class constructors, prototypes, and any top-level
  1793  * functions and constants associated with the standard classes (e.g. isNaN
  1794  * for Number).
  1796  * NB: This sets cx's global object to obj if it was null.
  1797  */
  1798 extern JS_PUBLIC_API(bool)
  1799 JS_InitStandardClasses(JSContext *cx, JS::Handle<JSObject*> obj);
  1801 /*
  1802  * Resolve id, which must contain either a string or an int, to a standard
  1803  * class name in obj if possible, defining the class's constructor and/or
  1804  * prototype and storing true in *resolved.  If id does not name a standard
  1805  * class or a top-level property induced by initializing a standard class,
  1806  * store false in *resolved and just return true.  Return false on error,
  1807  * as usual for bool result-typed API entry points.
  1809  * This API can be called directly from a global object class's resolve op,
  1810  * to define standard classes lazily.  The class's enumerate op should call
  1811  * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
  1812  * loops any classes not yet resolved lazily.
  1813  */
  1814 extern JS_PUBLIC_API(bool)
  1815 JS_ResolveStandardClass(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *resolved);
  1817 extern JS_PUBLIC_API(bool)
  1818 JS_EnumerateStandardClasses(JSContext *cx, JS::HandleObject obj);
  1820 extern JS_PUBLIC_API(bool)
  1821 JS_GetClassObject(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
  1823 extern JS_PUBLIC_API(bool)
  1824 JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
  1826 namespace JS {
  1828 /*
  1829  * Determine if the given object is an instance or prototype for a standard
  1830  * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
  1831  */
  1833 extern JS_PUBLIC_API(JSProtoKey)
  1834 IdentifyStandardInstance(JSObject *obj);
  1836 extern JS_PUBLIC_API(JSProtoKey)
  1837 IdentifyStandardPrototype(JSObject *obj);
  1839 extern JS_PUBLIC_API(JSProtoKey)
  1840 IdentifyStandardInstanceOrPrototype(JSObject *obj);
  1842 } /* namespace JS */
  1844 extern JS_PUBLIC_API(JSProtoKey)
  1845 JS_IdToProtoKey(JSContext *cx, JS::HandleId id);
  1847 /*
  1848  * Returns the original value of |Function.prototype| from the global object in
  1849  * which |forObj| was created.
  1850  */
  1851 extern JS_PUBLIC_API(JSObject *)
  1852 JS_GetFunctionPrototype(JSContext *cx, JS::HandleObject forObj);
  1854 /*
  1855  * Returns the original value of |Object.prototype| from the global object in
  1856  * which |forObj| was created.
  1857  */
  1858 extern JS_PUBLIC_API(JSObject *)
  1859 JS_GetObjectPrototype(JSContext *cx, JS::HandleObject forObj);
  1861 /*
  1862  * Returns the original value of |Array.prototype| from the global object in
  1863  * which |forObj| was created.
  1864  */
  1865 extern JS_PUBLIC_API(JSObject *)
  1866 JS_GetArrayPrototype(JSContext *cx, JS::HandleObject forObj);
  1868 extern JS_PUBLIC_API(JSObject *)
  1869 JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
  1871 extern JS_PUBLIC_API(bool)
  1872 JS_IsGlobalObject(JSObject *obj);
  1874 /*
  1875  * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
  1876  * or if |c|'s global has been collected.
  1877  */
  1878 extern JS_PUBLIC_API(JSObject *)
  1879 JS_GetGlobalForCompartmentOrNull(JSContext *cx, JSCompartment *c);
  1881 namespace JS {
  1883 extern JS_PUBLIC_API(JSObject *)
  1884 CurrentGlobalOrNull(JSContext *cx);
  1888 /*
  1889  * Initialize the 'Reflect' object on a global object.
  1890  */
  1891 extern JS_PUBLIC_API(JSObject *)
  1892 JS_InitReflect(JSContext *cx, JS::HandleObject global);
  1894 #ifdef JS_HAS_CTYPES
  1895 /*
  1896  * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
  1897  * object will be sealed.
  1898  */
  1899 extern JS_PUBLIC_API(bool)
  1900 JS_InitCTypesClass(JSContext *cx, JS::HandleObject global);
  1902 /*
  1903  * Convert a unicode string 'source' of length 'slen' to the platform native
  1904  * charset, returning a null-terminated string allocated with JS_malloc. On
  1905  * failure, this function should report an error.
  1906  */
  1907 typedef char *
  1908 (* JSCTypesUnicodeToNativeFun)(JSContext *cx, const jschar *source, size_t slen);
  1910 /*
  1911  * Set of function pointers that ctypes can use for various internal functions.
  1912  * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
  1913  * and will result in the applicable ctypes functionality not being available.
  1914  */
  1915 struct JSCTypesCallbacks {
  1916     JSCTypesUnicodeToNativeFun unicodeToNative;
  1917 };
  1919 typedef struct JSCTypesCallbacks JSCTypesCallbacks;
  1921 /*
  1922  * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
  1923  * pointer to static data that exists for the lifetime of 'ctypesObj', but it
  1924  * may safely be altered after calling this function and without having
  1925  * to call this function again.
  1926  */
  1927 extern JS_PUBLIC_API(void)
  1928 JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks *callbacks);
  1929 #endif
  1931 typedef bool
  1932 (* JSEnumerateDiagnosticMemoryCallback)(void *ptr, size_t length);
  1934 /*
  1935  * Enumerate memory regions that contain diagnostic information
  1936  * intended to be included in crash report minidumps.
  1937  */
  1938 extern JS_PUBLIC_API(void)
  1939 JS_EnumerateDiagnosticMemoryRegions(JSEnumerateDiagnosticMemoryCallback callback);
  1941 extern JS_PUBLIC_API(void *)
  1942 JS_malloc(JSContext *cx, size_t nbytes);
  1944 extern JS_PUBLIC_API(void *)
  1945 JS_realloc(JSContext *cx, void *p, size_t nbytes);
  1947 /*
  1948  * A wrapper for js_free(p) that may delay js_free(p) invocation as a
  1949  * performance optimization.
  1950  * cx may be nullptr.
  1951  */
  1952 extern JS_PUBLIC_API(void)
  1953 JS_free(JSContext *cx, void *p);
  1955 /*
  1956  * A wrapper for js_free(p) that may delay js_free(p) invocation as a
  1957  * performance optimization as specified by the given JSFreeOp instance.
  1958  */
  1959 extern JS_PUBLIC_API(void)
  1960 JS_freeop(JSFreeOp *fop, void *p);
  1962 extern JS_PUBLIC_API(JSFreeOp *)
  1963 JS_GetDefaultFreeOp(JSRuntime *rt);
  1965 extern JS_PUBLIC_API(void)
  1966 JS_updateMallocCounter(JSContext *cx, size_t nbytes);
  1968 extern JS_PUBLIC_API(char *)
  1969 JS_strdup(JSContext *cx, const char *s);
  1971 /* Duplicate a string.  Does not report an error on failure. */
  1972 extern JS_PUBLIC_API(char *)
  1973 JS_strdup(JSRuntime *rt, const char *s);
  1975 namespace JS {
  1977 /*
  1978  * A GC root is a pointer to a jsval, JSObject * or JSString * that itself
  1979  * points into the GC heap. JS_AddValueRoot takes a pointer to a jsval and
  1980  * JS_AddGCThingRoot takes a pointer to a JSObject * or JString *.
  1982  * Note that, since JS_Add*Root stores the address of a variable (of type
  1983  * jsval, JSString *, or JSObject *), that variable must live until
  1984  * JS_Remove*Root is called to remove that variable. For example, after:
  1986  *   void some_function() {
  1987  *     jsval v;
  1988  *     JS_AddNamedValueRoot(cx, &v, "name");
  1990  * the caller must perform
  1992  *     JS_RemoveValueRoot(cx, &v);
  1994  * before some_function() returns.
  1996  * Also, use JS_AddNamed*Root(cx, &structPtr->memberObj, "structPtr->memberObj")
  1997  * in preference to JS_Add*Root(cx, &structPtr->memberObj), in order to identify
  1998  * roots by their source callsites.  This way, you can find the callsite while
  1999  * debugging if you should fail to do JS_Remove*Root(cx, &structPtr->memberObj)
  2000  * before freeing structPtr's memory.
  2001  */
  2002 extern JS_PUBLIC_API(bool)
  2003 AddValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
  2005 extern JS_PUBLIC_API(bool)
  2006 AddStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
  2008 extern JS_PUBLIC_API(bool)
  2009 AddObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
  2011 extern JS_PUBLIC_API(bool)
  2012 AddNamedValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp, const char *name);
  2014 extern JS_PUBLIC_API(bool)
  2015 AddNamedValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp, const char *name);
  2017 extern JS_PUBLIC_API(bool)
  2018 AddNamedStringRoot(JSContext *cx, JS::Heap<JSString *> *rp, const char *name);
  2020 extern JS_PUBLIC_API(bool)
  2021 AddNamedObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp, const char *name);
  2023 extern JS_PUBLIC_API(bool)
  2024 AddNamedScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp, const char *name);
  2026 extern JS_PUBLIC_API(void)
  2027 RemoveValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
  2029 extern JS_PUBLIC_API(void)
  2030 RemoveStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
  2032 extern JS_PUBLIC_API(void)
  2033 RemoveObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
  2035 extern JS_PUBLIC_API(void)
  2036 RemoveScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp);
  2038 extern JS_PUBLIC_API(void)
  2039 RemoveValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp);
  2041 extern JS_PUBLIC_API(void)
  2042 RemoveStringRootRT(JSRuntime *rt, JS::Heap<JSString *> *rp);
  2044 extern JS_PUBLIC_API(void)
  2045 RemoveObjectRootRT(JSRuntime *rt, JS::Heap<JSObject *> *rp);
  2047 extern JS_PUBLIC_API(void)
  2048 RemoveScriptRootRT(JSRuntime *rt, JS::Heap<JSScript *> *rp);
  2050 } /* namespace JS */
  2052 /*
  2053  * Register externally maintained GC roots.
  2055  * traceOp: the trace operation. For each root the implementation should call
  2056  *          JS_CallTracer whenever the root contains a traceable thing.
  2057  * data:    the data argument to pass to each invocation of traceOp.
  2058  */
  2059 extern JS_PUBLIC_API(bool)
  2060 JS_AddExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
  2062 /* Undo a call to JS_AddExtraGCRootsTracer. */
  2063 extern JS_PUBLIC_API(void)
  2064 JS_RemoveExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
  2066 #ifdef JS_DEBUG
  2068 /*
  2069  * Debug-only method to dump the object graph of heap-allocated things.
  2071  * fp:              file for the dump output.
  2072  * start:           when non-null, dump only things reachable from start
  2073  *                  thing. Otherwise dump all things reachable from the
  2074  *                  runtime roots.
  2075  * startKind:       trace kind of start if start is not null. Must be
  2076  *                  JSTRACE_OBJECT when start is null.
  2077  * thingToFind:     dump only paths in the object graph leading to thingToFind
  2078  *                  when non-null.
  2079  * maxDepth:        the upper bound on the number of edges to descend from the
  2080  *                  graph roots.
  2081  * thingToIgnore:   thing to ignore during the graph traversal when non-null.
  2082  */
  2083 extern JS_PUBLIC_API(bool)
  2084 JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind kind,
  2085             void *thingToFind, size_t maxDepth, void *thingToIgnore);
  2087 #endif
  2089 /*
  2090  * Garbage collector API.
  2091  */
  2092 extern JS_PUBLIC_API(void)
  2093 JS_GC(JSRuntime *rt);
  2095 extern JS_PUBLIC_API(void)
  2096 JS_MaybeGC(JSContext *cx);
  2098 extern JS_PUBLIC_API(void)
  2099 JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb, void *data);
  2101 extern JS_PUBLIC_API(void)
  2102 JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
  2104 extern JS_PUBLIC_API(bool)
  2105 JS_IsGCMarkingTracer(JSTracer *trc);
  2107 /* For assertions only. */
  2108 #ifdef JS_DEBUG
  2109 extern JS_PUBLIC_API(bool)
  2110 JS_IsMarkingGray(JSTracer *trc);
  2111 #endif
  2113 /*
  2114  * JS_IsAboutToBeFinalized checks if the given object is going to be finalized
  2115  * at the end of the current GC. When called outside of the context of a GC,
  2116  * this function will return false. Typically this function is used on weak
  2117  * references, where the reference should be nulled out or destroyed if the
  2118  * given object is about to be finalized.
  2120  * The argument to JS_IsAboutToBeFinalized is an in-out param: when the
  2121  * function returns false, the object being referenced is still alive, but the
  2122  * garbage collector might have moved it. In this case, the reference passed
  2123  * to JS_IsAboutToBeFinalized will be updated to the object's new location.
  2124  * Callers of this method are responsible for updating any state that is
  2125  * dependent on the object's address. For example, if the object's address is
  2126  * used as a key in a hashtable, then the object must be removed and
  2127  * re-inserted with the correct hash.
  2128  */
  2129 extern JS_PUBLIC_API(bool)
  2130 JS_IsAboutToBeFinalized(JS::Heap<JSObject *> *objp);
  2132 extern JS_PUBLIC_API(bool)
  2133 JS_IsAboutToBeFinalizedUnbarriered(JSObject **objp);
  2135 typedef enum JSGCParamKey {
  2136     /* Maximum nominal heap before last ditch GC. */
  2137     JSGC_MAX_BYTES          = 0,
  2139     /* Number of JS_malloc bytes before last ditch GC. */
  2140     JSGC_MAX_MALLOC_BYTES   = 1,
  2142     /* Amount of bytes allocated by the GC. */
  2143     JSGC_BYTES = 3,
  2145     /* Number of times when GC was invoked. */
  2146     JSGC_NUMBER = 4,
  2148     /* Max size of the code cache in bytes. */
  2149     JSGC_MAX_CODE_CACHE_BYTES = 5,
  2151     /* Select GC mode. */
  2152     JSGC_MODE = 6,
  2154     /* Number of cached empty GC chunks. */
  2155     JSGC_UNUSED_CHUNKS = 7,
  2157     /* Total number of allocated GC chunks. */
  2158     JSGC_TOTAL_CHUNKS = 8,
  2160     /* Max milliseconds to spend in an incremental GC slice. */
  2161     JSGC_SLICE_TIME_BUDGET = 9,
  2163     /* Maximum size the GC mark stack can grow to. */
  2164     JSGC_MARK_STACK_LIMIT = 10,
  2166     /*
  2167      * GCs less than this far apart in time will be considered 'high-frequency GCs'.
  2168      * See setGCLastBytes in jsgc.cpp.
  2169      */
  2170     JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
  2172     /* Start of dynamic heap growth. */
  2173     JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
  2175     /* End of dynamic heap growth. */
  2176     JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
  2178     /* Upper bound of heap growth. */
  2179     JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
  2181     /* Lower bound of heap growth. */
  2182     JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
  2184     /* Heap growth for low frequency GCs. */
  2185     JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
  2187     /*
  2188      * If false, the heap growth factor is fixed at 3. If true, it is determined
  2189      * based on whether GCs are high- or low- frequency.
  2190      */
  2191     JSGC_DYNAMIC_HEAP_GROWTH = 17,
  2193     /* If true, high-frequency GCs will use a longer mark slice. */
  2194     JSGC_DYNAMIC_MARK_SLICE = 18,
  2196     /* Lower limit after which we limit the heap growth. */
  2197     JSGC_ALLOCATION_THRESHOLD = 19,
  2199     /*
  2200      * We decommit memory lazily. If more than this number of megabytes is
  2201      * available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
  2202      * to decommit it.
  2203      */
  2204     JSGC_DECOMMIT_THRESHOLD = 20
  2205 } JSGCParamKey;
  2207 extern JS_PUBLIC_API(void)
  2208 JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32_t value);
  2210 extern JS_PUBLIC_API(uint32_t)
  2211 JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key);
  2213 extern JS_PUBLIC_API(void)
  2214 JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32_t value);
  2216 extern JS_PUBLIC_API(uint32_t)
  2217 JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
  2219 extern JS_PUBLIC_API(void)
  2220 JS_SetGCParametersBasedOnAvailableMemory(JSRuntime *rt, uint32_t availMem);
  2222 /*
  2223  * Create a new JSString whose chars member refers to external memory, i.e.,
  2224  * memory requiring application-specific finalization.
  2225  */
  2226 extern JS_PUBLIC_API(JSString *)
  2227 JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
  2228                      const JSStringFinalizer *fin);
  2230 /*
  2231  * Return whether 'str' was created with JS_NewExternalString or
  2232  * JS_NewExternalStringWithClosure.
  2233  */
  2234 extern JS_PUBLIC_API(bool)
  2235 JS_IsExternalString(JSString *str);
  2237 /*
  2238  * Return the 'closure' arg passed to JS_NewExternalStringWithClosure or
  2239  * nullptr if the external string was created via JS_NewExternalString.
  2240  */
  2241 extern JS_PUBLIC_API(const JSStringFinalizer *)
  2242 JS_GetExternalStringFinalizer(JSString *str);
  2244 /*
  2245  * Set the size of the native stack that should not be exceed. To disable
  2246  * stack size checking pass 0.
  2248  * SpiderMonkey allows for a distinction between system code (such as GCs, which
  2249  * may incidentally be triggered by script but are not strictly performed on
  2250  * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
  2251  * and untrusted script. Each kind of code may have a different stack quota,
  2252  * allowing embedders to keep higher-priority machinery running in the face of
  2253  * scripted stack exhaustion by something else.
  2255  * The stack quotas for each kind of code should be monotonically descending,
  2256  * and may be specified with this function. If 0 is passed for a given kind
  2257  * of code, it defaults to the value of the next-highest-priority kind.
  2258  */
  2259 extern JS_PUBLIC_API(void)
  2260 JS_SetNativeStackQuota(JSRuntime *cx, size_t systemCodeStackSize,
  2261                        size_t trustedScriptStackSize = 0,
  2262                        size_t untrustedScriptStackSize = 0);
  2264 /************************************************************************/
  2266 extern JS_PUBLIC_API(int)
  2267 JS_IdArrayLength(JSContext *cx, JSIdArray *ida);
  2269 extern JS_PUBLIC_API(jsid)
  2270 JS_IdArrayGet(JSContext *cx, JSIdArray *ida, int index);
  2272 extern JS_PUBLIC_API(void)
  2273 JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
  2275 namespace JS {
  2277 class AutoIdArray : private AutoGCRooter
  2279   public:
  2280     AutoIdArray(JSContext *cx, JSIdArray *ida
  2281                 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  2282       : AutoGCRooter(cx, IDARRAY), context(cx), idArray(ida)
  2284         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  2286     ~AutoIdArray() {
  2287         if (idArray)
  2288             JS_DestroyIdArray(context, idArray);
  2290     bool operator!() {
  2291         return !idArray;
  2293     jsid operator[](size_t i) const {
  2294         JS_ASSERT(idArray);
  2295         return JS_IdArrayGet(context, idArray, i);
  2297     size_t length() const {
  2298         return JS_IdArrayLength(context, idArray);
  2301     friend void AutoGCRooter::trace(JSTracer *trc);
  2303     JSIdArray *steal() {
  2304         JSIdArray *copy = idArray;
  2305         idArray = nullptr;
  2306         return copy;
  2309   protected:
  2310     inline void trace(JSTracer *trc);
  2312   private:
  2313     JSContext *context;
  2314     JSIdArray *idArray;
  2315     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  2317     /* No copy or assignment semantics. */
  2318     AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
  2319     void operator=(AutoIdArray &ida) MOZ_DELETE;
  2320 };
  2322 } /* namespace JS */
  2324 extern JS_PUBLIC_API(bool)
  2325 JS_ValueToId(JSContext *cx, JS::HandleValue v, JS::MutableHandleId idp);
  2327 extern JS_PUBLIC_API(bool)
  2328 JS_StringToId(JSContext *cx, JS::HandleString s, JS::MutableHandleId idp);
  2330 extern JS_PUBLIC_API(bool)
  2331 JS_IdToValue(JSContext *cx, jsid id, JS::MutableHandle<JS::Value> vp);
  2333 /*
  2334  * Invoke the [[DefaultValue]] hook (see ES5 8.6.2) with the provided hint on
  2335  * the specified object, computing a primitive default value for the object.
  2336  * The hint must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no hint).  On
  2337  * success the resulting value is stored in *vp.
  2338  */
  2339 extern JS_PUBLIC_API(bool)
  2340 JS_DefaultValue(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint,
  2341                 JS::MutableHandle<JS::Value> vp);
  2343 extern JS_PUBLIC_API(bool)
  2344 JS_PropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  2345                 JS::MutableHandleValue vp);
  2347 extern JS_PUBLIC_API(bool)
  2348 JS_StrictPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
  2349                       JS::MutableHandleValue vp);
  2351 extern JS_PUBLIC_API(bool)
  2352 JS_DeletePropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  2353                       bool *succeeded);
  2355 extern JS_PUBLIC_API(bool)
  2356 JS_EnumerateStub(JSContext *cx, JS::HandleObject obj);
  2358 extern JS_PUBLIC_API(bool)
  2359 JS_ResolveStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
  2361 extern JS_PUBLIC_API(bool)
  2362 JS_ConvertStub(JSContext *cx, JS::HandleObject obj, JSType type,
  2363                JS::MutableHandleValue vp);
  2365 struct JSConstDoubleSpec {
  2366     double          dval;
  2367     const char      *name;
  2368     uint8_t         flags;
  2369     uint8_t         spare[3];
  2370 };
  2372 struct JSJitInfo;
  2374 /*
  2375  * Wrappers to replace {Strict,}PropertyOp for JSPropertySpecs. This will allow
  2376  * us to pass one JSJitInfo per function with the property spec, without
  2377  * additional field overhead.
  2378  */
  2379 typedef struct JSStrictPropertyOpWrapper {
  2380     JSStrictPropertyOp  op;
  2381     const JSJitInfo     *info;
  2382 } JSStrictPropertyOpWrapper;
  2384 typedef struct JSPropertyOpWrapper {
  2385     JSPropertyOp        op;
  2386     const JSJitInfo     *info;
  2387 } JSPropertyOpWrapper;
  2389 /*
  2390  * Wrapper to do as above, but for JSNatives for JSFunctionSpecs.
  2391  */
  2392 typedef struct JSNativeWrapper {
  2393     JSNative        op;
  2394     const JSJitInfo *info;
  2395 } JSNativeWrapper;
  2397 /*
  2398  * Macro static initializers which make it easy to pass no JSJitInfo as part of a
  2399  * JSPropertySpec or JSFunctionSpec.
  2400  */
  2401 #define JSOP_WRAPPER(op) { {op, nullptr} }
  2402 #define JSOP_NULLWRAPPER JSOP_WRAPPER(nullptr)
  2404 /*
  2405  * To define an array element rather than a named property member, cast the
  2406  * element's index to (const char *) and initialize name with it, and set the
  2407  * JSPROP_INDEX bit in flags.
  2408  */
  2409 struct JSPropertySpec {
  2410     struct SelfHostedWrapper {
  2411         void       *unused;
  2412         const char *funname;
  2413     };
  2415     const char                  *name;
  2416     uint8_t                     flags;
  2417     union {
  2418         JSPropertyOpWrapper propertyOp;
  2419         SelfHostedWrapper   selfHosted;
  2420     } getter;
  2421     union {
  2422         JSStrictPropertyOpWrapper propertyOp;
  2423         SelfHostedWrapper         selfHosted;
  2424     } setter;
  2426 private:
  2427     void StaticAsserts() {
  2428         JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSPropertyOpWrapper));
  2429         JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSStrictPropertyOpWrapper));
  2430         JS_STATIC_ASSERT(offsetof(SelfHostedWrapper, funname) ==
  2431                          offsetof(JSPropertyOpWrapper, info));
  2433 };
  2435 namespace JS {
  2436 namespace detail {
  2438 /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_NATIVE_TO only. */
  2439 inline int CheckIsNative(JSNative native);
  2441 /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_STRING_TO only. */
  2442 template<size_t N>
  2443 inline int
  2444 CheckIsCharacterLiteral(const char (&arr)[N]);
  2446 } // namespace detail
  2447 } // namespace JS
  2449 #define JS_CAST_NATIVE_TO(v, To) \
  2450   (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
  2451    reinterpret_cast<To>(v))
  2453 #define JS_CAST_STRING_TO(s, To) \
  2454   (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
  2455    reinterpret_cast<To>(s))
  2457 #define JS_CHECK_ACCESSOR_FLAGS(flags) \
  2458   (static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))>::Type>(0), \
  2459    (flags))
  2461 /*
  2462  * JSPropertySpec uses JSAPI JSPropertyOp and JSStrictPropertyOp in function
  2463  * signatures.  These macros encapsulate the definition of JSNative-backed
  2464  * JSPropertySpecs, performing type-safe casts on the getter/setter functions
  2465  * and adding the necessary property flags to trigger interpretation as
  2466  * JSNatives.
  2467  */
  2468 #define JS_PSG(name, getter, flags) \
  2469     {name, \
  2470      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
  2471      JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
  2472      JSOP_NULLWRAPPER}
  2473 #define JS_PSGS(name, getter, setter, flags) \
  2474     {name, \
  2475      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
  2476      JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
  2477      JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
  2478 #define JS_SELF_HOSTED_GET(name, getterName, flags) \
  2479     {name, \
  2480      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
  2481      { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
  2482      JSOP_NULLWRAPPER }
  2483 #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
  2484     {name, \
  2485      uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
  2486      { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) },  \
  2487      { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } }
  2488 #define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
  2490 /*
  2491  * To define a native function, set call to a JSNativeWrapper. To define a
  2492  * self-hosted function, set selfHostedName to the name of a function
  2493  * compiled during JSRuntime::initSelfHosting.
  2494  */
  2495 struct JSFunctionSpec {
  2496     const char      *name;
  2497     JSNativeWrapper call;
  2498     uint16_t        nargs;
  2499     uint16_t        flags;
  2500     const char      *selfHostedName;
  2501 };
  2503 /*
  2504  * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
  2505  * that's passed to JS_DefineFunctions or JS_InitClass.
  2506  */
  2507 #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
  2509 /*
  2510  * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
  2511  * homage to the old JSNative/JSFastNative split) simply adds the flag
  2512  * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
  2513  * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally
  2514  * JS_FNSPEC has slots for all the fields.
  2515  */
  2516 #define JS_FS(name,call,nargs,flags)                                          \
  2517     JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
  2518 #define JS_FN(name,call,nargs,flags)                                          \
  2519     JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
  2520 #define JS_FNINFO(name,call,info,nargs,flags)                                 \
  2521     JS_FNSPEC(name, call, info, nargs, flags, nullptr)
  2522 #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags)                    \
  2523     JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
  2524 #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName)                  \
  2525     {name, {call, info}, nargs, flags, selfHostedName}
  2527 extern JS_PUBLIC_API(JSObject *)
  2528 JS_InitClass(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent_proto,
  2529              const JSClass *clasp, JSNative constructor, unsigned nargs,
  2530              const JSPropertySpec *ps, const JSFunctionSpec *fs,
  2531              const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs);
  2533 /*
  2534  * Set up ctor.prototype = proto and proto.constructor = ctor with the
  2535  * right property flags.
  2536  */
  2537 extern JS_PUBLIC_API(bool)
  2538 JS_LinkConstructorAndPrototype(JSContext *cx, JS::Handle<JSObject*> ctor,
  2539                                JS::Handle<JSObject*> proto);
  2541 extern JS_PUBLIC_API(const JSClass *)
  2542 JS_GetClass(JSObject *obj);
  2544 extern JS_PUBLIC_API(bool)
  2545 JS_InstanceOf(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp, JS::CallArgs *args);
  2547 extern JS_PUBLIC_API(bool)
  2548 JS_HasInstance(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool *bp);
  2550 extern JS_PUBLIC_API(void *)
  2551 JS_GetPrivate(JSObject *obj);
  2553 extern JS_PUBLIC_API(void)
  2554 JS_SetPrivate(JSObject *obj, void *data);
  2556 extern JS_PUBLIC_API(void *)
  2557 JS_GetInstancePrivate(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp,
  2558                       JS::CallArgs *args);
  2560 extern JS_PUBLIC_API(bool)
  2561 JS_GetPrototype(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject protop);
  2563 extern JS_PUBLIC_API(bool)
  2564 JS_SetPrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
  2566 extern JS_PUBLIC_API(JSObject *)
  2567 JS_GetParent(JSObject *obj);
  2569 extern JS_PUBLIC_API(bool)
  2570 JS_SetParent(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent);
  2572 extern JS_PUBLIC_API(JSObject *)
  2573 JS_GetConstructor(JSContext *cx, JS::Handle<JSObject*> proto);
  2575 namespace JS {
  2577 enum ZoneSpecifier {
  2578     FreshZone = 0,
  2579     SystemZone = 1
  2580 };
  2582 class JS_PUBLIC_API(CompartmentOptions)
  2584   public:
  2585     class Override {
  2586       public:
  2587         Override() : mode_(Default) {}
  2589         bool get(bool defaultValue) const {
  2590             if (mode_ == Default)
  2591                 return defaultValue;
  2592             return mode_ == ForceTrue;
  2593         };
  2595         void set(bool overrideValue) {
  2596             mode_ = overrideValue ? ForceTrue : ForceFalse;
  2597         };
  2599         void reset() {
  2600             mode_ = Default;
  2603       private:
  2604         enum Mode {
  2605             Default,
  2606             ForceTrue,
  2607             ForceFalse
  2608         };
  2610         Mode mode_;
  2611     };
  2613     explicit CompartmentOptions()
  2614       : version_(JSVERSION_UNKNOWN)
  2615       , invisibleToDebugger_(false)
  2616       , mergeable_(false)
  2617       , discardSource_(false)
  2618       , traceGlobal_(nullptr)
  2619       , singletonsAsTemplates_(true)
  2621         zone_.spec = JS::FreshZone;
  2624     JSVersion version() const { return version_; }
  2625     CompartmentOptions &setVersion(JSVersion aVersion) {
  2626         MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
  2627         version_ = aVersion;
  2628         return *this;
  2631     // Certain scopes (i.e. XBL compilation scopes) are implementation details
  2632     // of the embedding, and references to them should never leak out to script.
  2633     // This flag causes the this compartment to skip firing onNewGlobalObject
  2634     // and makes addDebuggee a no-op for this global.
  2635     bool invisibleToDebugger() const { return invisibleToDebugger_; }
  2636     CompartmentOptions &setInvisibleToDebugger(bool flag) {
  2637         invisibleToDebugger_ = flag;
  2638         return *this;
  2641     // Compartments used for off-thread compilation have their contents merged
  2642     // into a target compartment when the compilation is finished. This is only
  2643     // allowed if this flag is set.  The invisibleToDebugger flag must also be
  2644     // set for such compartments.
  2645     bool mergeable() const { return mergeable_; }
  2646     CompartmentOptions &setMergeable(bool flag) {
  2647         mergeable_ = flag;
  2648         return *this;
  2651     // For certain globals, we know enough about the code that will run in them
  2652     // that we can discard script source entirely.
  2653     bool discardSource() const { return discardSource_; }
  2654     CompartmentOptions &setDiscardSource(bool flag) {
  2655         discardSource_ = flag;
  2656         return *this;
  2660     bool cloneSingletons(JSContext *cx) const;
  2661     Override &cloneSingletonsOverride() { return cloneSingletonsOverride_; }
  2663     void *zonePointer() const {
  2664         JS_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
  2665         return zone_.pointer;
  2667     ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
  2668     CompartmentOptions &setZone(ZoneSpecifier spec);
  2669     CompartmentOptions &setSameZoneAs(JSObject *obj);
  2671     void setSingletonsAsValues() {
  2672         singletonsAsTemplates_ = false;
  2674     bool getSingletonsAsTemplates() const {
  2675         return singletonsAsTemplates_;
  2676     };
  2678     CompartmentOptions &setTrace(JSTraceOp op) {
  2679         traceGlobal_ = op;
  2680         return *this;
  2682     JSTraceOp getTrace() const {
  2683         return traceGlobal_;
  2686   private:
  2687     JSVersion version_;
  2688     bool invisibleToDebugger_;
  2689     bool mergeable_;
  2690     bool discardSource_;
  2691     Override cloneSingletonsOverride_;
  2692     union {
  2693         ZoneSpecifier spec;
  2694         void *pointer; // js::Zone* is not exposed in the API.
  2695     } zone_;
  2696     JSTraceOp traceGlobal_;
  2698     // To XDR singletons, we need to ensure that all singletons are all used as
  2699     // templates, by making JSOP_OBJECT return a clone of the JSScript
  2700     // singleton, instead of returning the value which is baked in the JSScript.
  2701     bool singletonsAsTemplates_;
  2702 };
  2704 JS_PUBLIC_API(CompartmentOptions &)
  2705 CompartmentOptionsRef(JSCompartment *compartment);
  2707 JS_PUBLIC_API(CompartmentOptions &)
  2708 CompartmentOptionsRef(JSObject *obj);
  2710 JS_PUBLIC_API(CompartmentOptions &)
  2711 CompartmentOptionsRef(JSContext *cx);
  2713 // During global creation, we fire notifications to callbacks registered
  2714 // via the Debugger API. These callbacks are arbitrary script, and can touch
  2715 // the global in arbitrary ways. When that happens, the global should not be
  2716 // in a half-baked state. But this creates a problem for consumers that need
  2717 // to set slots on the global to put it in a consistent state.
  2718 //
  2719 // This API provides a way for consumers to set slots atomically (immediately
  2720 // after the global is created), before any debugger hooks are fired. It's
  2721 // unfortunately on the clunky side, but that's the way the cookie crumbles.
  2722 //
  2723 // If callers have no additional state on the global to set up, they may pass
  2724 // |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
  2725 // fire the hook as its final act before returning. Otherwise, callers should
  2726 // pass |DontFireOnNewGlobalHook|, which means that they are responsible for
  2727 // invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
  2728 // an error occurs and the operation aborts, callers should skip firing the
  2729 // hook. But otherwise, callers must take care to fire the hook exactly once
  2730 // before compiling any script in the global's scope (we have assertions in
  2731 // place to enforce this). This lets us be sure that debugger clients never miss
  2732 // breakpoints.
  2733 enum OnNewGlobalHookOption {
  2734     FireOnNewGlobalHook,
  2735     DontFireOnNewGlobalHook
  2736 };
  2738 } /* namespace JS */
  2740 extern JS_PUBLIC_API(JSObject *)
  2741 JS_NewGlobalObject(JSContext *cx, const JSClass *clasp, JSPrincipals *principals,
  2742                    JS::OnNewGlobalHookOption hookOption,
  2743                    const JS::CompartmentOptions &options = JS::CompartmentOptions());
  2744 /*
  2745  * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
  2746  * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
  2747  * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
  2748  * object, from which we can be sure the compartment is relevant, and mark it.
  2750  * It is still possible to specify custom trace hooks for global object classes. They can be
  2751  * provided via the CompartmentOptions passed to JS_NewGlobalObject.
  2752  */
  2753 extern JS_PUBLIC_API(void)
  2754 JS_GlobalObjectTraceHook(JSTracer *trc, JSObject *global);
  2756 extern JS_PUBLIC_API(void)
  2757 JS_FireOnNewGlobalObject(JSContext *cx, JS::HandleObject global);
  2759 extern JS_PUBLIC_API(JSObject *)
  2760 JS_NewObject(JSContext *cx, const JSClass *clasp, JS::Handle<JSObject*> proto,
  2761              JS::Handle<JSObject*> parent);
  2763 /* Queries the [[Extensible]] property of the object. */
  2764 extern JS_PUBLIC_API(bool)
  2765 JS_IsExtensible(JSContext *cx, JS::HandleObject obj, bool *extensible);
  2767 extern JS_PUBLIC_API(bool)
  2768 JS_IsNative(JSObject *obj);
  2770 extern JS_PUBLIC_API(JSRuntime *)
  2771 JS_GetObjectRuntime(JSObject *obj);
  2773 /*
  2774  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
  2775  * proto if proto's actual parameter value is null.
  2776  */
  2777 extern JS_PUBLIC_API(JSObject *)
  2778 JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *clasp, JS::Handle<JSObject*> proto,
  2779                            JS::Handle<JSObject*> parent);
  2781 /*
  2782  * Freeze obj, and all objects it refers to, recursively. This will not recurse
  2783  * through non-extensible objects, on the assumption that those are already
  2784  * deep-frozen.
  2785  */
  2786 extern JS_PUBLIC_API(bool)
  2787 JS_DeepFreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
  2789 /*
  2790  * Freezes an object; see ES5's Object.freeze(obj) method.
  2791  */
  2792 extern JS_PUBLIC_API(bool)
  2793 JS_FreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
  2795 extern JS_PUBLIC_API(bool)
  2796 JS_PreventExtensions(JSContext *cx, JS::HandleObject obj);
  2798 extern JS_PUBLIC_API(JSObject *)
  2799 JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
  2801 extern JS_PUBLIC_API(JSObject *)
  2802 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp,
  2803                 JSObject *proto, unsigned attrs);
  2805 extern JS_PUBLIC_API(bool)
  2806 JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
  2808 extern JS_PUBLIC_API(bool)
  2809 JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *ps);
  2811 extern JS_PUBLIC_API(bool)
  2812 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue value,
  2813                   unsigned attrs,
  2814                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2816 extern JS_PUBLIC_API(bool)
  2817 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleObject value,
  2818                   unsigned attrs,
  2819                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2821 extern JS_PUBLIC_API(bool)
  2822 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleString value,
  2823                   unsigned attrs,
  2824                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2826 extern JS_PUBLIC_API(bool)
  2827 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, int32_t value,
  2828                   unsigned attrs,
  2829                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2831 extern JS_PUBLIC_API(bool)
  2832 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, uint32_t value,
  2833                   unsigned attrs,
  2834                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2836 extern JS_PUBLIC_API(bool)
  2837 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, double value,
  2838                   unsigned attrs,
  2839                   JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
  2841 extern JS_PUBLIC_API(bool)
  2842 JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
  2843                       JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
  2845 extern JS_PUBLIC_API(bool)
  2846 JS_DefineOwnProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  2847                      JS::HandleValue descriptor, bool *bp);
  2849 extern JS_PUBLIC_API(bool)
  2850 JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
  2851                          bool *foundp);
  2853 extern JS_PUBLIC_API(bool)
  2854 JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  2855                              bool *foundp);
  2857 extern JS_PUBLIC_API(bool)
  2858 JS_HasProperty(JSContext *cx, JS::HandleObject obj, const char *name, bool *foundp);
  2860 extern JS_PUBLIC_API(bool)
  2861 JS_HasPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
  2863 extern JS_PUBLIC_API(bool)
  2864 JS_LookupProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
  2866 extern JS_PUBLIC_API(bool)
  2867 JS_LookupPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  2868                       JS::MutableHandleValue vp);
  2870 struct JSPropertyDescriptor {
  2871     JSObject           *obj;
  2872     unsigned           attrs;
  2873     JSPropertyOp       getter;
  2874     JSStrictPropertyOp setter;
  2875     JS::Value          value;
  2877     JSPropertyDescriptor()
  2878       : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JSVAL_VOID)
  2879     {}
  2881     void trace(JSTracer *trc);
  2882 };
  2884 namespace JS {
  2886 template <typename Outer>
  2887 class PropertyDescriptorOperations
  2889     const JSPropertyDescriptor * desc() const { return static_cast<const Outer*>(this)->extract(); }
  2891   public:
  2892     bool isEnumerable() const { return desc()->attrs & JSPROP_ENUMERATE; }
  2893     bool isReadonly() const { return desc()->attrs & JSPROP_READONLY; }
  2894     bool isPermanent() const { return desc()->attrs & JSPROP_PERMANENT; }
  2895     bool hasNativeAccessors() const { return desc()->attrs & JSPROP_NATIVE_ACCESSORS; }
  2896     bool hasGetterObject() const { return desc()->attrs & JSPROP_GETTER; }
  2897     bool hasSetterObject() const { return desc()->attrs & JSPROP_SETTER; }
  2898     bool hasGetterOrSetterObject() const { return desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER); }
  2899     bool isShared() const { return desc()->attrs & JSPROP_SHARED; }
  2900     bool isIndex() const { return desc()->attrs & JSPROP_INDEX; }
  2901     bool hasAttributes(unsigned attrs) const { return desc()->attrs & attrs; }
  2903     JS::HandleObject object() const {
  2904         return JS::HandleObject::fromMarkedLocation(&desc()->obj);
  2906     unsigned attributes() const { return desc()->attrs; }
  2907     JSPropertyOp getter() const { return desc()->getter; }
  2908     JSStrictPropertyOp setter() const { return desc()->setter; }
  2909     JS::HandleObject getterObject() const {
  2910         MOZ_ASSERT(hasGetterObject());
  2911         return JS::HandleObject::fromMarkedLocation(
  2912                 reinterpret_cast<JSObject *const *>(&desc()->getter));
  2914     JS::HandleObject setterObject() const {
  2915         MOZ_ASSERT(hasSetterObject());
  2916         return JS::HandleObject::fromMarkedLocation(
  2917                 reinterpret_cast<JSObject *const *>(&desc()->setter));
  2919     JS::HandleValue value() const {
  2920         return JS::HandleValue::fromMarkedLocation(&desc()->value);
  2922 };
  2924 template <typename Outer>
  2925 class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
  2927     JSPropertyDescriptor * desc() { return static_cast<Outer*>(this)->extractMutable(); }
  2929   public:
  2931     void clear() {
  2932         object().set(nullptr);
  2933         setAttributes(0);
  2934         setGetter(nullptr);
  2935         setSetter(nullptr);
  2936         value().setUndefined();
  2939     JS::MutableHandleObject object() {
  2940         return JS::MutableHandleObject::fromMarkedLocation(&desc()->obj);
  2942     unsigned &attributesRef() { return desc()->attrs; }
  2943     JSPropertyOp &getter() { return desc()->getter; }
  2944     JSStrictPropertyOp &setter() { return desc()->setter; }
  2945     JS::MutableHandleValue value() {
  2946         return JS::MutableHandleValue::fromMarkedLocation(&desc()->value);
  2949     void setEnumerable() { desc()->attrs |= JSPROP_ENUMERATE; }
  2950     void setAttributes(unsigned attrs) { desc()->attrs = attrs; }
  2952     void setGetter(JSPropertyOp op) { desc()->getter = op; }
  2953     void setSetter(JSStrictPropertyOp op) { desc()->setter = op; }
  2954     void setGetterObject(JSObject *obj) { desc()->getter = reinterpret_cast<JSPropertyOp>(obj); }
  2955     void setSetterObject(JSObject *obj) { desc()->setter = reinterpret_cast<JSStrictPropertyOp>(obj); }
  2956 };
  2958 } /* namespace JS */
  2960 namespace js {
  2962 template <>
  2963 struct GCMethods<JSPropertyDescriptor> {
  2964     static JSPropertyDescriptor initial() { return JSPropertyDescriptor(); }
  2965     static ThingRootKind kind() { return THING_ROOT_PROPERTY_DESCRIPTOR; }
  2966     static bool poisoned(const JSPropertyDescriptor &desc) {
  2967         return (desc.obj && JS::IsPoisonedPtr(desc.obj)) ||
  2968                (desc.attrs & JSPROP_GETTER && desc.getter && JS::IsPoisonedPtr(desc.getter)) ||
  2969                (desc.attrs & JSPROP_SETTER && desc.setter && JS::IsPoisonedPtr(desc.setter)) ||
  2970                (desc.value.isGCThing() && JS::IsPoisonedPtr(desc.value.toGCThing()));
  2972 };
  2974 template <>
  2975 class RootedBase<JSPropertyDescriptor>
  2976   : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >
  2978     friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
  2979     friend class JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
  2980     const JSPropertyDescriptor *extract() const {
  2981         return static_cast<const JS::Rooted<JSPropertyDescriptor>*>(this)->address();
  2983     JSPropertyDescriptor *extractMutable() {
  2984         return static_cast<JS::Rooted<JSPropertyDescriptor>*>(this)->address();
  2986 };
  2988 template <>
  2989 class HandleBase<JSPropertyDescriptor>
  2990   : public JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor> >
  2992     friend class JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor> >;
  2993     const JSPropertyDescriptor *extract() const {
  2994         return static_cast<const JS::Handle<JSPropertyDescriptor>*>(this)->address();
  2996 };
  2998 template <>
  2999 class MutableHandleBase<JSPropertyDescriptor>
  3000   : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >
  3002     friend class JS::PropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >;
  3003     friend class JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >;
  3004     const JSPropertyDescriptor *extract() const {
  3005         return static_cast<const JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
  3007     JSPropertyDescriptor *extractMutable() {
  3008         return static_cast<JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
  3010 };
  3012 } /* namespace js */
  3014 extern JS_PUBLIC_API(bool)
  3015 JS_GetOwnPropertyDescriptorById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  3016                                 JS::MutableHandle<JSPropertyDescriptor> desc);
  3018 extern JS_PUBLIC_API(bool)
  3019 JS_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
  3020                             JS::MutableHandle<JSPropertyDescriptor> desc);
  3022 /*
  3023  * Like JS_GetOwnPropertyDescriptorById but will return a property on
  3024  * an object on the prototype chain (returned in desc->obj). If desc->obj is null,
  3025  * then this property was not found on the prototype chain.
  3026  */
  3027 extern JS_PUBLIC_API(bool)
  3028 JS_GetPropertyDescriptorById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
  3029                              JS::MutableHandle<JSPropertyDescriptor> desc);
  3031 extern JS_PUBLIC_API(bool)
  3032 JS_GetPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
  3033                          JS::MutableHandle<JSPropertyDescriptor> desc);
  3035 extern JS_PUBLIC_API(bool)
  3036 JS_GetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
  3038 extern JS_PUBLIC_API(bool)
  3039 JS_GetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp);
  3041 extern JS_PUBLIC_API(bool)
  3042 JS_ForwardGetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject onBehalfOf,
  3043                         JS::MutableHandleValue vp);
  3045 extern JS_PUBLIC_API(bool)
  3046 JS_SetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue v);
  3048 extern JS_PUBLIC_API(bool)
  3049 JS_SetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
  3051 extern JS_PUBLIC_API(bool)
  3052 JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
  3054 extern JS_PUBLIC_API(bool)
  3055 JS_DeleteProperty2(JSContext *cx, JS::HandleObject obj, const char *name, bool *succeeded);
  3057 extern JS_PUBLIC_API(bool)
  3058 JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
  3060 extern JS_PUBLIC_API(bool)
  3061 JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
  3063 extern JS_PUBLIC_API(bool)
  3064 JS_DefineUCProperty(JSContext *cx, JSObject *obj,
  3065                     const jschar *name, size_t namelen, jsval value,
  3066                     JSPropertyOp getter, JSStrictPropertyOp setter,
  3067                     unsigned attrs);
  3069 extern JS_PUBLIC_API(bool)
  3070 JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
  3071                            size_t namelen, bool *foundp);
  3073 extern JS_PUBLIC_API(bool)
  3074 JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
  3075                  const jschar *name, size_t namelen,
  3076                  bool *vp);
  3078 extern JS_PUBLIC_API(bool)
  3079 JS_LookupUCProperty(JSContext *cx, JS::HandleObject obj,
  3080                     const jschar *name, size_t namelen,
  3081                     JS::MutableHandleValue vp);
  3083 extern JS_PUBLIC_API(bool)
  3084 JS_GetUCProperty(JSContext *cx, JS::HandleObject obj,
  3085                  const jschar *name, size_t namelen,
  3086                  JS::MutableHandleValue vp);
  3088 extern JS_PUBLIC_API(bool)
  3089 JS_SetUCProperty(JSContext *cx, JS::HandleObject obj,
  3090                  const jschar *name, size_t namelen,
  3091                  JS::HandleValue v);
  3093 extern JS_PUBLIC_API(bool)
  3094 JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
  3095                      bool *succeeded);
  3097 extern JS_PUBLIC_API(JSObject *)
  3098 JS_NewArrayObject(JSContext *cx, const JS::HandleValueArray& contents);
  3100 extern JS_PUBLIC_API(JSObject *)
  3101 JS_NewArrayObject(JSContext *cx, size_t length);
  3103 extern JS_PUBLIC_API(bool)
  3104 JS_IsArrayObject(JSContext *cx, JS::HandleValue value);
  3106 extern JS_PUBLIC_API(bool)
  3107 JS_IsArrayObject(JSContext *cx, JS::HandleObject obj);
  3109 extern JS_PUBLIC_API(bool)
  3110 JS_GetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t *lengthp);
  3112 extern JS_PUBLIC_API(bool)
  3113 JS_SetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t length);
  3115 extern JS_PUBLIC_API(bool)
  3116 JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,
  3117                  JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
  3119 extern JS_PUBLIC_API(bool)
  3120 JS_AlreadyHasOwnElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
  3122 extern JS_PUBLIC_API(bool)
  3123 JS_HasElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
  3125 extern JS_PUBLIC_API(bool)
  3126 JS_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
  3128 extern JS_PUBLIC_API(bool)
  3129 JS_GetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
  3131 extern JS_PUBLIC_API(bool)
  3132 JS_ForwardGetElementTo(JSContext *cx, JS::HandleObject obj, uint32_t index,
  3133                        JS::HandleObject onBehalfOf, JS::MutableHandleValue vp);
  3135 extern JS_PUBLIC_API(bool)
  3136 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
  3138 extern JS_PUBLIC_API(bool)
  3139 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
  3141 extern JS_PUBLIC_API(bool)
  3142 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
  3144 extern JS_PUBLIC_API(bool)
  3145 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, int32_t v);
  3147 extern JS_PUBLIC_API(bool)
  3148 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, uint32_t v);
  3150 extern JS_PUBLIC_API(bool)
  3151 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, double v);
  3153 extern JS_PUBLIC_API(bool)
  3154 JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index);
  3156 extern JS_PUBLIC_API(bool)
  3157 JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
  3159 /*
  3160  * Remove all configurable properties from the given (non-global) object and
  3161  * assign undefined to all writable data properties.
  3162  */
  3163 JS_PUBLIC_API(void)
  3164 JS_ClearNonGlobalObject(JSContext *cx, JS::HandleObject obj);
  3166 /*
  3167  * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
  3168  * done for all slots, regardless of the associated property descriptor.
  3169  */
  3170 JS_PUBLIC_API(void)
  3171 JS_SetAllNonReservedSlotsToUndefined(JSContext *cx, JSObject *objArg);
  3173 /*
  3174  * Create a new array buffer with the given contents. On success, the ownership
  3175  * is transferred to the new array buffer.
  3176  */
  3177 extern JS_PUBLIC_API(JSObject *)
  3178 JS_NewArrayBufferWithContents(JSContext *cx, size_t nbytes, void *contents);
  3180 /*
  3181  * Steal the contents of the given array buffer. The array buffer has its
  3182  * length set to 0 and its contents array cleared. The caller takes ownership
  3183  * of the return value and must free it or transfer ownership via
  3184  * JS_NewArrayBufferWithContents when done using it.
  3185  */
  3186 extern JS_PUBLIC_API(void *)
  3187 JS_StealArrayBufferContents(JSContext *cx, JS::HandleObject obj);
  3189 /*
  3190  * Allocate memory that may be eventually passed to
  3191  * JS_NewArrayBufferWithContents. |maybecx| is optional; if a non-nullptr cx is
  3192  * given, it will be used for memory accounting and OOM reporting. |nbytes| is
  3193  * the number of payload bytes required.
  3194  */
  3195 extern JS_PUBLIC_API(void *)
  3196 JS_AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes);
  3198 /*
  3199  * Reallocate memory allocated by JS_AllocateArrayBufferContents, growing or
  3200  * shrinking it as appropriate. If oldContents is null then this behaves like
  3201  * JS_AllocateArrayBufferContents.
  3202  */
  3203 extern JS_PUBLIC_API(void *)
  3204 JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void *oldContents, uint32_t oldNbytes);
  3206 /*
  3207  * Create a new mapped array buffer with the given memory mapped contents. On success,
  3208  * the ownership is transferred to the new mapped array buffer.
  3209  */
  3210 extern JS_PUBLIC_API(JSObject *)
  3211 JS_NewMappedArrayBufferWithContents(JSContext *cx, size_t nbytes, void *contents);
  3213 /*
  3214  * Create memory mapped array buffer contents.
  3215  * Caller must take care of closing fd after calling this function.
  3216  */
  3217 extern JS_PUBLIC_API(void *)
  3218 JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
  3220 /*
  3221  * Release the allocated resource of mapped array buffer contents before the
  3222  * object is created.
  3223  * If a new object has been created by JS_NewMappedArrayBufferWithContents()
  3224  * with this content, then JS_NeuterArrayBuffer() should be used instead to
  3225  * release the resource used by the object.
  3226  */
  3227 extern JS_PUBLIC_API(void)
  3228 JS_ReleaseMappedArrayBufferContents(void *contents, size_t length);
  3230 extern JS_PUBLIC_API(JSIdArray *)
  3231 JS_Enumerate(JSContext *cx, JS::HandleObject obj);
  3233 /*
  3234  * Create an object to iterate over enumerable properties of obj, in arbitrary
  3235  * property definition order.  NB: This differs from longstanding for..in loop
  3236  * order, which uses order of property definition in obj.
  3237  */
  3238 extern JS_PUBLIC_API(JSObject *)
  3239 JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
  3241 /*
  3242  * Return true on success with *idp containing the id of the next enumerable
  3243  * property to visit using iterobj, or JSID_IS_VOID if there is no such property
  3244  * left to visit.  Return false on error.
  3245  */
  3246 extern JS_PUBLIC_API(bool)
  3247 JS_NextProperty(JSContext *cx, JS::Handle<JSObject*> iterobj, jsid *idp);
  3249 extern JS_PUBLIC_API(jsval)
  3250 JS_GetReservedSlot(JSObject *obj, uint32_t index);
  3252 extern JS_PUBLIC_API(void)
  3253 JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v);
  3255 /************************************************************************/
  3257 /*
  3258  * Functions and scripts.
  3259  */
  3260 extern JS_PUBLIC_API(JSFunction *)
  3261 JS_NewFunction(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
  3262                JS::Handle<JSObject*> parent, const char *name);
  3264 /*
  3265  * Create the function with the name given by the id. JSID_IS_STRING(id) must
  3266  * be true.
  3267  */
  3268 extern JS_PUBLIC_API(JSFunction *)
  3269 JS_NewFunctionById(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
  3270                    JS::Handle<JSObject*> parent, JS::Handle<jsid> id);
  3272 namespace JS {
  3274 extern JS_PUBLIC_API(JSFunction *)
  3275 GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, JS::Handle<jsid> id,
  3276                       unsigned nargs);
  3278 } /* namespace JS */
  3280 extern JS_PUBLIC_API(JSObject *)
  3281 JS_GetFunctionObject(JSFunction *fun);
  3283 /*
  3284  * Return the function's identifier as a JSString, or null if fun is unnamed.
  3285  * The returned string lives as long as fun, so you don't need to root a saved
  3286  * reference to it if fun is well-connected or rooted, and provided you bound
  3287  * the use of the saved reference by fun's lifetime.
  3288  */
  3289 extern JS_PUBLIC_API(JSString *)
  3290 JS_GetFunctionId(JSFunction *fun);
  3292 /*
  3293  * Return a function's display name. This is the defined name if one was given
  3294  * where the function was defined, or it could be an inferred name by the JS
  3295  * engine in the case that the function was defined to be anonymous. This can
  3296  * still return nullptr if a useful display name could not be inferred. The
  3297  * same restrictions on rooting as those in JS_GetFunctionId apply.
  3298  */
  3299 extern JS_PUBLIC_API(JSString *)
  3300 JS_GetFunctionDisplayId(JSFunction *fun);
  3302 /*
  3303  * Return the arity (length) of fun.
  3304  */
  3305 extern JS_PUBLIC_API(uint16_t)
  3306 JS_GetFunctionArity(JSFunction *fun);
  3308 /*
  3309  * Infallible predicate to test whether obj is a function object (faster than
  3310  * comparing obj's class name to "Function", but equivalent unless someone has
  3311  * overwritten the "Function" identifier with a different constructor and then
  3312  * created instances using that constructor that might be passed in as obj).
  3313  */
  3314 extern JS_PUBLIC_API(bool)
  3315 JS_ObjectIsFunction(JSContext *cx, JSObject *obj);
  3317 extern JS_PUBLIC_API(bool)
  3318 JS_ObjectIsCallable(JSContext *cx, JSObject *obj);
  3320 extern JS_PUBLIC_API(bool)
  3321 JS_IsNativeFunction(JSObject *funobj, JSNative call);
  3323 /* Return whether the given function is a valid constructor. */
  3324 extern JS_PUBLIC_API(bool)
  3325 JS_IsConstructor(JSFunction *fun);
  3327 /*
  3328  * Bind the given callable to use the given object as "this".
  3330  * If |callable| is not callable, will throw and return nullptr.
  3331  */
  3332 extern JS_PUBLIC_API(JSObject*)
  3333 JS_BindCallable(JSContext *cx, JS::Handle<JSObject*> callable, JS::Handle<JSObject*> newThis);
  3335 extern JS_PUBLIC_API(bool)
  3336 JS_DefineFunctions(JSContext *cx, JS::Handle<JSObject*> obj, const JSFunctionSpec *fs);
  3338 extern JS_PUBLIC_API(JSFunction *)
  3339 JS_DefineFunction(JSContext *cx, JS::Handle<JSObject*> obj, const char *name, JSNative call,
  3340                   unsigned nargs, unsigned attrs);
  3342 extern JS_PUBLIC_API(JSFunction *)
  3343 JS_DefineUCFunction(JSContext *cx, JS::Handle<JSObject*> obj,
  3344                     const jschar *name, size_t namelen, JSNative call,
  3345                     unsigned nargs, unsigned attrs);
  3347 extern JS_PUBLIC_API(JSFunction *)
  3348 JS_DefineFunctionById(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
  3349                       unsigned nargs, unsigned attrs);
  3351 /*
  3352  * Clone a top-level function into a new scope. This function will dynamically
  3353  * fail if funobj was lexically nested inside some other function.
  3354  */
  3355 extern JS_PUBLIC_API(JSObject *)
  3356 JS_CloneFunctionObject(JSContext *cx, JS::Handle<JSObject*> funobj, JS::Handle<JSObject*> parent);
  3358 /*
  3359  * Given a buffer, return false if the buffer might become a valid
  3360  * javascript statement with the addition of more lines.  Otherwise return
  3361  * true.  The intent is to support interactive compilation - accumulate
  3362  * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
  3363  * the compiler.
  3364  */
  3365 extern JS_PUBLIC_API(bool)
  3366 JS_BufferIsCompilableUnit(JSContext *cx, JS::Handle<JSObject*> obj, const char *utf8,
  3367                           size_t length);
  3369 extern JS_PUBLIC_API(JSScript *)
  3370 JS_CompileScript(JSContext *cx, JS::HandleObject obj,
  3371                  const char *ascii, size_t length,
  3372                  const JS::CompileOptions &options);
  3374 extern JS_PUBLIC_API(JSScript *)
  3375 JS_CompileUCScript(JSContext *cx, JS::HandleObject obj,
  3376                    const jschar *chars, size_t length,
  3377                    const JS::CompileOptions &options);
  3379 extern JS_PUBLIC_API(JSObject *)
  3380 JS_GetGlobalFromScript(JSScript *script);
  3382 extern JS_PUBLIC_API(JSFunction *)
  3383 JS_CompileFunction(JSContext *cx, JS::HandleObject obj, const char *name,
  3384                    unsigned nargs, const char *const *argnames,
  3385                    const char *bytes, size_t length,
  3386                    const JS::CompileOptions &options);
  3388 extern JS_PUBLIC_API(JSFunction *)
  3389 JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
  3390                      unsigned nargs, const char *const *argnames,
  3391                      const jschar *chars, size_t length,
  3392                      const JS::CompileOptions &options);
  3394 namespace JS {
  3396 /* Options for JavaScript compilation. */
  3398 /*
  3399  * In the most common use case, a CompileOptions instance is allocated on the
  3400  * stack, and holds non-owning references to non-POD option values: strings;
  3401  * principals; objects; and so on. The code declaring the instance guarantees
  3402  * that such option values will outlive the CompileOptions itself: objects are
  3403  * otherwise rooted; principals have had their reference counts bumped; strings
  3404  * will not be freed until the CompileOptions goes out of scope. In this
  3405  * situation, CompileOptions only refers to things others own, so it can be
  3406  * lightweight.
  3408  * In some cases, however, we need to hold compilation options with a
  3409  * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
  3410  * compilation options where a worker thread can find them, and then return
  3411  * immediately. The worker thread will come along at some later point, and use
  3412  * the options.
  3414  * The compiler itself just needs to be able to access a collection of options;
  3415  * it doesn't care who owns them, or what's keeping them alive. It does its own
  3416  * addrefs/copies/tracing/etc.
  3418  * So, we have a class hierarchy that reflects these three use cases:
  3420  * - ReadOnlyCompileOptions is the common base class. It can be used by code
  3421  *   that simply needs to access options set elsewhere, like the compiler.
  3423  * - The usual CompileOptions class must be stack-allocated, and holds
  3424  *   non-owning references to the filename, element, and so on. It's derived
  3425  *   from ReadOnlyCompileOptions, so the compiler can use it.
  3427  * - OwningCompileOptions roots / copies / reference counts of all its values,
  3428  *   and unroots / frees / releases them when it is destructed. It too is
  3429  *   derived from ReadOnlyCompileOptions, so the compiler accepts it.
  3430  */
  3432 /*
  3433  * The common base class for the CompileOptions hierarchy.
  3435  * Use this in code that only needs to access compilation options created
  3436  * elsewhere, like the compiler. Don't instantiate this class (the constructor
  3437  * is protected anyway); instead, create instances only of the derived classes:
  3438  * CompileOptions and OwningCompileOptions.
  3439  */
  3440 class JS_FRIEND_API(ReadOnlyCompileOptions)
  3442     friend class CompileOptions;
  3444   protected:
  3445     JSPrincipals *originPrincipals_;
  3446     const char *filename_;
  3447     const char *introducerFilename_;
  3448     const jschar *sourceMapURL_;
  3450     // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
  3451     // is unusable until that's set to something more specific; the derived
  3452     // classes' constructors take care of that, in ways appropriate to their
  3453     // purpose.
  3454     ReadOnlyCompileOptions()
  3455       : originPrincipals_(nullptr),
  3456         filename_(nullptr),
  3457         introducerFilename_(nullptr),
  3458         sourceMapURL_(nullptr),
  3459         version(JSVERSION_UNKNOWN),
  3460         versionSet(false),
  3461         utf8(false),
  3462         lineno(1),
  3463         column(0),
  3464         compileAndGo(false),
  3465         forEval(false),
  3466         defineOnScope(true),
  3467         noScriptRval(false),
  3468         selfHostingMode(false),
  3469         canLazilyParse(true),
  3470         strictOption(false),
  3471         extraWarningsOption(false),
  3472         werrorOption(false),
  3473         asmJSOption(false),
  3474         forceAsync(false),
  3475         installedFile(false),
  3476         sourceIsLazy(false),
  3477         introductionType(nullptr),
  3478         introductionLineno(0),
  3479         introductionOffset(0),
  3480         hasIntroductionInfo(false)
  3481     { }
  3483     // Set all POD options (those not requiring reference counts, copies,
  3484     // rooting, or other hand-holding) to their values in |rhs|.
  3485     void copyPODOptions(const ReadOnlyCompileOptions &rhs);
  3487   public:
  3488     // Read-only accessors for non-POD options. The proper way to set these
  3489     // depends on the derived type.
  3490     JSPrincipals *originPrincipals(js::ExclusiveContext *cx) const;
  3491     const char *filename() const { return filename_; }
  3492     const char *introducerFilename() const { return introducerFilename_; }
  3493     const jschar *sourceMapURL() const { return sourceMapURL_; }
  3494     virtual JSObject *element() const = 0;
  3495     virtual JSString *elementAttributeName() const = 0;
  3496     virtual JSScript *introductionScript() const = 0;
  3498     // POD options.
  3499     JSVersion version;
  3500     bool versionSet;
  3501     bool utf8;
  3502     unsigned lineno;
  3503     unsigned column;
  3504     bool compileAndGo;
  3505     bool forEval;
  3506     bool defineOnScope;
  3507     bool noScriptRval;
  3508     bool selfHostingMode;
  3509     bool canLazilyParse;
  3510     bool strictOption;
  3511     bool extraWarningsOption;
  3512     bool werrorOption;
  3513     bool asmJSOption;
  3514     bool forceAsync;
  3515     bool installedFile;  // 'true' iff pre-compiling js file in packaged app
  3516     bool sourceIsLazy;
  3518     // |introductionType| is a statically allocated C string:
  3519     // one of "eval", "Function", or "GeneratorFunction".
  3520     const char *introductionType;
  3521     unsigned introductionLineno;
  3522     uint32_t introductionOffset;
  3523     bool hasIntroductionInfo;
  3525     // Wrap any compilation option values that need it as appropriate for
  3526     // use from |compartment|.
  3527     virtual bool wrap(JSContext *cx, JSCompartment *compartment) = 0;
  3529   private:
  3530     static JSObject * const nullObjectPtr;
  3531     void operator=(const ReadOnlyCompileOptions &) MOZ_DELETE;
  3532 };
  3534 /*
  3535  * Compilation options, with dynamic lifetime. An instance of this type
  3536  * makes a copy of / holds / roots all dynamically allocated resources
  3537  * (principals; elements; strings) that it refers to. Its destructor frees
  3538  * / drops / unroots them. This is heavier than CompileOptions, below, but
  3539  * unlike CompileOptions, it can outlive any given stack frame.
  3541  * Note that this *roots* any JS values it refers to - they're live
  3542  * unconditionally. Thus, instances of this type can't be owned, directly
  3543  * or indirectly, by a JavaScript object: if any value that this roots ever
  3544  * comes to refer to the object that owns this, then the whole cycle, and
  3545  * anything else it entrains, will never be freed.
  3546  */
  3547 class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
  3549     JSRuntime *runtime;
  3550     PersistentRootedObject elementRoot;
  3551     PersistentRootedString elementAttributeNameRoot;
  3552     PersistentRootedScript introductionScriptRoot;
  3554   public:
  3555     // A minimal constructor, for use with OwningCompileOptions::copy. This
  3556     // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
  3557     // shouldn't be used until we've set that to something real (as |copy|
  3558     // will).
  3559     explicit OwningCompileOptions(JSContext *cx);
  3560     ~OwningCompileOptions();
  3562     JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
  3563     JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
  3564     JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
  3566     // Set this to a copy of |rhs|. Return false on OOM.
  3567     bool copy(JSContext *cx, const ReadOnlyCompileOptions &rhs);
  3569     /* These setters make copies of their string arguments, and are fallible. */
  3570     bool setFile(JSContext *cx, const char *f);
  3571     bool setFileAndLine(JSContext *cx, const char *f, unsigned l);
  3572     bool setSourceMapURL(JSContext *cx, const jschar *s);
  3573     bool setIntroducerFilename(JSContext *cx, const char *s);
  3575     /* These setters are infallible, and can be chained. */
  3576     OwningCompileOptions &setLine(unsigned l)             { lineno = l;              return *this; }
  3577     OwningCompileOptions &setElement(JSObject *e) {
  3578         elementRoot = e;
  3579         return *this;
  3581     OwningCompileOptions &setElementAttributeName(JSString *p) {
  3582         elementAttributeNameRoot = p;
  3583         return *this;
  3585     OwningCompileOptions &setIntroductionScript(JSScript *s) {
  3586         introductionScriptRoot = s;
  3587         return *this;
  3589     OwningCompileOptions &setOriginPrincipals(JSPrincipals *p) {
  3590         if (p) JS_HoldPrincipals(p);
  3591         if (originPrincipals_) JS_DropPrincipals(runtime, originPrincipals_);
  3592         originPrincipals_ = p;
  3593         return *this;
  3595     OwningCompileOptions &setVersion(JSVersion v) {
  3596         version = v;
  3597         versionSet = true;
  3598         return *this;
  3600     OwningCompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
  3601     OwningCompileOptions &setColumn(unsigned c) { column = c; return *this; }
  3602     OwningCompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
  3603     OwningCompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
  3604     OwningCompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
  3605     OwningCompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
  3606     OwningCompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
  3607     OwningCompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
  3608     OwningCompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
  3609     OwningCompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
  3610     bool setIntroductionInfo(JSContext *cx, const char *introducerFn, const char *intro,
  3611                              unsigned line, JSScript *script, uint32_t offset)
  3613         if (!setIntroducerFilename(cx, introducerFn))
  3614             return false;
  3615         introductionType = intro;
  3616         introductionLineno = line;
  3617         introductionScriptRoot = script;
  3618         introductionOffset = offset;
  3619         hasIntroductionInfo = true;
  3620         return true;
  3623     virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
  3625   private:
  3626     void operator=(const CompileOptions &rhs) MOZ_DELETE;
  3627 };
  3629 /*
  3630  * Compilation options stored on the stack. An instance of this type
  3631  * simply holds references to dynamically allocated resources (element;
  3632  * filename; source map URL) that are owned by something else. If you
  3633  * create an instance of this type, it's up to you to guarantee that
  3634  * everything you store in it will outlive it.
  3635  */
  3636 class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOptions
  3638     RootedObject elementRoot;
  3639     RootedString elementAttributeNameRoot;
  3640     RootedScript introductionScriptRoot;
  3642   public:
  3643     explicit CompileOptions(JSContext *cx, JSVersion version = JSVERSION_UNKNOWN);
  3644     CompileOptions(js::ContextFriendFields *cx, const ReadOnlyCompileOptions &rhs)
  3645       : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
  3646         introductionScriptRoot(cx)
  3648         copyPODOptions(rhs);
  3650         originPrincipals_ = rhs.originPrincipals_;
  3651         filename_ = rhs.filename();
  3652         sourceMapURL_ = rhs.sourceMapURL();
  3653         elementRoot = rhs.element();
  3654         elementAttributeNameRoot = rhs.elementAttributeName();
  3655         introductionScriptRoot = rhs.introductionScript();
  3658     JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
  3659     JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
  3660     JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
  3662     CompileOptions &setFile(const char *f) { filename_ = f; return *this; }
  3663     CompileOptions &setLine(unsigned l) { lineno = l; return *this; }
  3664     CompileOptions &setFileAndLine(const char *f, unsigned l) {
  3665         filename_ = f; lineno = l; return *this;
  3667     CompileOptions &setSourceMapURL(const jschar *s) { sourceMapURL_ = s;       return *this; }
  3668     CompileOptions &setElement(JSObject *e)          { elementRoot = e;         return *this; }
  3669     CompileOptions &setElementAttributeName(JSString *p) {
  3670         elementAttributeNameRoot = p;
  3671         return *this;
  3673     CompileOptions &setIntroductionScript(JSScript *s) {
  3674         introductionScriptRoot = s;
  3675         return *this;
  3677     CompileOptions &setOriginPrincipals(JSPrincipals *p) {
  3678         originPrincipals_ = p;
  3679         return *this;
  3681     CompileOptions &setVersion(JSVersion v) {
  3682         version = v;
  3683         versionSet = true;
  3684         return *this;
  3686     CompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
  3687     CompileOptions &setColumn(unsigned c) { column = c; return *this; }
  3688     CompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
  3689     CompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
  3690     CompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
  3691     CompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
  3692     CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
  3693     CompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
  3694     CompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
  3695     CompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
  3696     CompileOptions &setIntroductionInfo(const char *introducerFn, const char *intro,
  3697                                         unsigned line, JSScript *script, uint32_t offset)
  3699         introducerFilename_ = introducerFn;
  3700         introductionType = intro;
  3701         introductionLineno = line;
  3702         introductionScriptRoot = script;
  3703         introductionOffset = offset;
  3704         hasIntroductionInfo = true;
  3705         return *this;
  3708     virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
  3710   private:
  3711     void operator=(const CompileOptions &rhs) MOZ_DELETE;
  3712 };
  3714 /*
  3715  * |script| will always be set. On failure, it will be set to nullptr.
  3716  */
  3717 extern JS_PUBLIC_API(bool)
  3718 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3719         SourceBufferHolder &srcBuf, JS::MutableHandleScript script);
  3721 extern JS_PUBLIC_API(JSScript *)
  3722 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3723         const char *bytes, size_t length);
  3725 extern JS_PUBLIC_API(JSScript *)
  3726 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3727         const jschar *chars, size_t length);
  3729 extern JS_PUBLIC_API(JSScript *)
  3730 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, FILE *file);
  3732 extern JS_PUBLIC_API(JSScript *)
  3733 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename);
  3735 extern JS_PUBLIC_API(bool)
  3736 CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length);
  3738 /*
  3739  * Off thread compilation control flow.
  3741  * After successfully triggering an off thread compile of a script, the
  3742  * callback will eventually be invoked with the specified data and a token
  3743  * for the compilation. The callback will be invoked while off the main thread,
  3744  * so must ensure that its operations are thread safe. Afterwards,
  3745  * FinishOffThreadScript must be invoked on the main thread to get the result
  3746  * script or nullptr. If maybecx is not specified, the resources will be freed,
  3747  * but no script will be returned.
  3749  * The characters passed in to CompileOffThread must remain live until the
  3750  * callback is invoked, and the resulting script will be rooted until the call
  3751  * to FinishOffThreadScript.
  3752  */
  3754 extern JS_PUBLIC_API(bool)
  3755 CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
  3756                  const jschar *chars, size_t length,
  3757                  OffThreadCompileCallback callback, void *callbackData);
  3759 extern JS_PUBLIC_API(JSScript *)
  3760 FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token);
  3762 extern JS_PUBLIC_API(bool)
  3763 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3764                 const char *name, unsigned nargs, const char *const *argnames,
  3765                 SourceBufferHolder &srcBuf, JS::MutableHandleFunction fun);
  3767 extern JS_PUBLIC_API(JSFunction *)
  3768 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3769                 const char *name, unsigned nargs, const char *const *argnames,
  3770                 const char *bytes, size_t length);
  3772 extern JS_PUBLIC_API(JSFunction *)
  3773 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3774                 const char *name, unsigned nargs, const char *const *argnames,
  3775                 const jschar *chars, size_t length);
  3777 } /* namespace JS */
  3779 extern JS_PUBLIC_API(JSString *)
  3780 JS_DecompileScript(JSContext *cx, JS::Handle<JSScript*> script, const char *name, unsigned indent);
  3782 /*
  3783  * API extension: OR this into indent to avoid pretty-printing the decompiled
  3784  * source resulting from JS_DecompileFunction{,Body}.
  3785  */
  3786 #define JS_DONT_PRETTY_PRINT    ((unsigned)0x8000)
  3788 extern JS_PUBLIC_API(JSString *)
  3789 JS_DecompileFunction(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
  3791 extern JS_PUBLIC_API(JSString *)
  3792 JS_DecompileFunctionBody(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
  3794 /*
  3795  * NB: JS_ExecuteScript and the JS_Evaluate*Script* quadruplets use the obj
  3796  * parameter as the initial scope chain header, the 'this' keyword value, and
  3797  * the variables object (ECMA parlance for where 'var' and 'function' bind
  3798  * names) of the execution context for script.
  3800  * Using obj as the variables object is problematic if obj's parent (which is
  3801  * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in
  3802  * this case, variables created by 'var x = 0', e.g., go in obj, but variables
  3803  * created by assignment to an unbound id, 'x = 0', go in the last object on
  3804  * the scope chain linked by parent.
  3806  * ECMA calls that last scoping object the "global object", but note that many
  3807  * embeddings have several such objects.  ECMA requires that "global code" be
  3808  * executed with the variables object equal to this global object.  But these
  3809  * JS API entry points provide freedom to execute code against a "sub-global",
  3810  * i.e., a parented or scoped object, in which case the variables object will
  3811  * differ from the last object on the scope chain, resulting in confusing and
  3812  * non-ECMA explicit vs. implicit variable creation.
  3814  * Caveat embedders: unless you already depend on this buggy variables object
  3815  * binding behavior, you should call ContextOptionsRef(cx).setVarObjFix(true)
  3816  * for each context in the application, if you pass parented objects as the obj
  3817  * parameter, or may ever pass such objects in the future.
  3819  * Why a runtime option?  The alternative is to add six or so new API entry
  3820  * points with signatures matching the following six, and that doesn't seem
  3821  * worth the code bloat cost.  Such new entry points would probably have less
  3822  * obvious names, too, so would not tend to be used.  The JS_SetOption call,
  3823  * OTOH, can be more easily hacked into existing code that does not depend on
  3824  * the bug; such code can continue to use the familiar JS_EvaluateScript,
  3825  * etc., entry points.
  3826  */
  3827 extern JS_PUBLIC_API(bool)
  3828 JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, JS::MutableHandleValue rval);
  3830 extern JS_PUBLIC_API(bool)
  3831 JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script);
  3833 namespace JS {
  3835 /*
  3836  * Like the above, but handles a cross-compartment script. If the script is
  3837  * cross-compartment, it is cloned into the current compartment before executing.
  3838  */
  3839 extern JS_PUBLIC_API(bool)
  3840 CloneAndExecuteScript(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSScript*> script);
  3842 } /* namespace JS */
  3844 extern JS_PUBLIC_API(bool)
  3845 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
  3846                         JS::MutableHandleValue rval, JSVersion version);
  3848 extern JS_PUBLIC_API(bool)
  3849 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
  3850                         JSVersion version);
  3852 extern JS_PUBLIC_API(bool)
  3853 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
  3854                   const char *bytes, unsigned length,
  3855                   const char *filename, unsigned lineno,
  3856                   JS::MutableHandleValue rval);
  3858 extern JS_PUBLIC_API(bool)
  3859 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
  3860                   const char *bytes, unsigned length,
  3861                   const char *filename, unsigned lineno);
  3863 extern JS_PUBLIC_API(bool)
  3864 JS_EvaluateUCScript(JSContext *cx, JS::Handle<JSObject*> obj,
  3865                     const jschar *chars, unsigned length,
  3866                     const char *filename, unsigned lineno,
  3867                     JS::MutableHandle<JS::Value> rval);
  3869 namespace JS {
  3871 extern JS_PUBLIC_API(bool)
  3872 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3873          SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
  3875 extern JS_PUBLIC_API(bool)
  3876 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3877          const jschar *chars, size_t length, JS::MutableHandleValue rval);
  3879 extern JS_PUBLIC_API(bool)
  3880 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3881          const char *bytes, size_t length, JS::MutableHandleValue rval);
  3883 extern JS_PUBLIC_API(bool)
  3884 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3885          const char *filename, JS::MutableHandleValue rval);
  3887 extern JS_PUBLIC_API(bool)
  3888 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3889          SourceBufferHolder &srcBuf);
  3891 extern JS_PUBLIC_API(bool)
  3892 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3893          const jschar *chars, size_t length);
  3895 extern JS_PUBLIC_API(bool)
  3896 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3897          const char *bytes, size_t length);
  3899 extern JS_PUBLIC_API(bool)
  3900 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
  3901          const char *filename);
  3903 } /* namespace JS */
  3905 extern JS_PUBLIC_API(bool)
  3906 JS_CallFunction(JSContext *cx, JS::HandleObject obj, JS::HandleFunction fun,
  3907                 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  3909 extern JS_PUBLIC_API(bool)
  3910 JS_CallFunctionName(JSContext *cx, JS::HandleObject obj, const char *name,
  3911                     const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  3913 extern JS_PUBLIC_API(bool)
  3914 JS_CallFunctionValue(JSContext *cx, JS::HandleObject obj, JS::HandleValue fval,
  3915                      const JS::HandleValueArray& args, JS::MutableHandleValue rval);
  3917 namespace JS {
  3919 static inline bool
  3920 Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleFunction fun,
  3921      const JS::HandleValueArray &args, MutableHandleValue rval)
  3923     return !!JS_CallFunction(cx, thisObj, fun, args, rval);
  3926 static inline bool
  3927 Call(JSContext *cx, JS::HandleObject thisObj, const char *name, const JS::HandleValueArray& args,
  3928      MutableHandleValue rval)
  3930     return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
  3933 static inline bool
  3934 Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
  3935      MutableHandleValue rval)
  3937     return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
  3940 extern JS_PUBLIC_API(bool)
  3941 Call(JSContext *cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
  3942      MutableHandleValue rval);
  3944 static inline bool
  3945 Call(JSContext *cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
  3946      MutableHandleValue rval)
  3948     JS_ASSERT(funObj);
  3949     JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
  3950     return Call(cx, thisv, fun, args, rval);
  3953 } /* namespace JS */
  3955 /*
  3956  * These functions allow setting an interrupt callback that will be called
  3957  * from the JS thread some time after any thread triggered the callback using
  3958  * JS_RequestInterruptCallback(rt).
  3960  * To schedule the GC and for other activities the engine internally triggers
  3961  * interrupt callbacks. The embedding should thus not rely on callbacks being
  3962  * triggered through the external API only.
  3964  * Important note: Additional callbacks can occur inside the callback handler
  3965  * if it re-enters the JS engine. The embedding must ensure that the callback
  3966  * is disconnected before attempting such re-entry.
  3967  */
  3968 extern JS_PUBLIC_API(JSInterruptCallback)
  3969 JS_SetInterruptCallback(JSRuntime *rt, JSInterruptCallback callback);
  3971 extern JS_PUBLIC_API(JSInterruptCallback)
  3972 JS_GetInterruptCallback(JSRuntime *rt);
  3974 extern JS_PUBLIC_API(void)
  3975 JS_RequestInterruptCallback(JSRuntime *rt);
  3977 extern JS_PUBLIC_API(bool)
  3978 JS_IsRunning(JSContext *cx);
  3980 /*
  3981  * Saving and restoring frame chains.
  3983  * These two functions are used to set aside cx's call stack while that stack
  3984  * is inactive. After a call to JS_SaveFrameChain, it looks as if there is no
  3985  * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack
  3986  * must be balanced and all nested calls to JS_SaveFrameChain must have had
  3987  * matching JS_RestoreFrameChain calls.
  3989  * JS_SaveFrameChain deals with cx not having any code running on it.
  3990  */
  3991 extern JS_PUBLIC_API(bool)
  3992 JS_SaveFrameChain(JSContext *cx);
  3994 extern JS_PUBLIC_API(void)
  3995 JS_RestoreFrameChain(JSContext *cx);
  3997 #ifdef MOZ_TRACE_JSCALLS
  3998 /*
  3999  * The callback is expected to be quick and noninvasive. It should not
  4000  * request interrupts, turn on debugging, or produce uncaught JS
  4001  * exceptions. The state of the stack and registers in the context
  4002  * cannot be relied upon, since this callback may be invoked directly
  4003  * from either JIT. The 'entering' field means we are entering a
  4004  * function if it is positive, leaving a function if it is zero or
  4005  * negative.
  4006  */
  4007 extern JS_PUBLIC_API(void)
  4008 JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
  4010 extern JS_PUBLIC_API(JSFunctionCallback)
  4011 JS_GetFunctionCallback(JSContext *cx);
  4012 #endif /* MOZ_TRACE_JSCALLS */
  4014 /************************************************************************/
  4016 /*
  4017  * Strings.
  4019  * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
  4020  * but on error (signified by null return), it leaves chars owned by the
  4021  * caller. So the caller must free bytes in the error case, if it has no use
  4022  * for them. In contrast, all the JS_New*StringCopy* functions do not take
  4023  * ownership of the character memory passed to them -- they copy it.
  4024  */
  4025 extern JS_PUBLIC_API(JSString *)
  4026 JS_NewStringCopyN(JSContext *cx, const char *s, size_t n);
  4028 extern JS_PUBLIC_API(JSString *)
  4029 JS_NewStringCopyZ(JSContext *cx, const char *s);
  4031 extern JS_PUBLIC_API(JSString *)
  4032 JS_InternJSString(JSContext *cx, JS::HandleString str);
  4034 extern JS_PUBLIC_API(JSString *)
  4035 JS_InternStringN(JSContext *cx, const char *s, size_t length);
  4037 extern JS_PUBLIC_API(JSString *)
  4038 JS_InternString(JSContext *cx, const char *s);
  4040 extern JS_PUBLIC_API(JSString *)
  4041 JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
  4043 extern JS_PUBLIC_API(JSString *)
  4044 JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
  4046 extern JS_PUBLIC_API(JSString *)
  4047 JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
  4049 extern JS_PUBLIC_API(JSString *)
  4050 JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
  4052 extern JS_PUBLIC_API(JSString *)
  4053 JS_InternUCString(JSContext *cx, const jschar *s);
  4055 extern JS_PUBLIC_API(bool)
  4056 JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
  4058 extern JS_PUBLIC_API(bool)
  4059 JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, bool *match);
  4061 extern JS_PUBLIC_API(size_t)
  4062 JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote);
  4064 extern JS_PUBLIC_API(bool)
  4065 JS_FileEscapedString(FILE *fp, JSString *str, char quote);
  4067 /*
  4068  * Extracting string characters and length.
  4070  * While getting the length of a string is infallible, getting the chars can
  4071  * fail. As indicated by the lack of a JSContext parameter, there are two
  4072  * special cases where getting the chars is infallible:
  4074  * The first case is interned strings, i.e., strings from JS_InternString or
  4075  * JSID_TO_STRING(id), using JS_GetInternedStringChars*.
  4077  * The second case is "flat" strings that have been explicitly prepared in a
  4078  * fallible context by JS_FlattenString. To catch errors, a separate opaque
  4079  * JSFlatString type is returned by JS_FlattenString and expected by
  4080  * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
  4081  * distinction: the input and output of JS_FlattenString are the same actual
  4082  * GC-thing so only one needs to be rooted. If a JSString is known to be flat,
  4083  * JS_ASSERT_STRING_IS_FLAT can be used to make a debug-checked cast. Example:
  4085  *   // in a fallible context
  4086  *   JSFlatString *fstr = JS_FlattenString(cx, str);
  4087  *   if (!fstr)
  4088  *     return false;
  4089  *   JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
  4091  *   // in an infallible context, for the same 'str'
  4092  *   const jschar *chars = JS_GetFlatStringChars(fstr)
  4093  *   JS_ASSERT(chars);
  4095  * The CharsZ APIs guarantee that the returned array has a null character at
  4096  * chars[length]. This can require additional copying so clients should prefer
  4097  * APIs without CharsZ if possible. The infallible functions also return
  4098  * null-terminated arrays. (There is no additional cost or non-Z alternative
  4099  * for the infallible functions, so 'Z' is left out of the identifier.)
  4100  */
  4102 extern JS_PUBLIC_API(size_t)
  4103 JS_GetStringLength(JSString *str);
  4105 extern JS_PUBLIC_API(const jschar *)
  4106 JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
  4108 extern JS_PUBLIC_API(const jschar *)
  4109 JS_GetInternedStringChars(JSString *str);
  4111 extern JS_PUBLIC_API(const jschar *)
  4112 JS_GetInternedStringCharsAndLength(JSString *str, size_t *length);
  4114 extern JS_PUBLIC_API(const jschar *)
  4115 JS_GetStringCharsZ(JSContext *cx, JSString *str);
  4117 extern JS_PUBLIC_API(const jschar *)
  4118 JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length);
  4120 extern JS_PUBLIC_API(JSFlatString *)
  4121 JS_FlattenString(JSContext *cx, JSString *str);
  4123 extern JS_PUBLIC_API(const jschar *)
  4124 JS_GetFlatStringChars(JSFlatString *str);
  4126 static MOZ_ALWAYS_INLINE JSFlatString *
  4127 JSID_TO_FLAT_STRING(jsid id)
  4129     JS_ASSERT(JSID_IS_STRING(id));
  4130     return (JSFlatString *)(JSID_BITS(id));
  4133 static MOZ_ALWAYS_INLINE JSFlatString *
  4134 JS_ASSERT_STRING_IS_FLAT(JSString *str)
  4136     JS_ASSERT(JS_GetFlatStringChars((JSFlatString *)str));
  4137     return (JSFlatString *)str;
  4140 static MOZ_ALWAYS_INLINE JSString *
  4141 JS_FORGET_STRING_FLATNESS(JSFlatString *fstr)
  4143     return (JSString *)fstr;
  4146 /*
  4147  * Additional APIs that avoid fallibility when given a flat string.
  4148  */
  4150 extern JS_PUBLIC_API(bool)
  4151 JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes);
  4153 extern JS_PUBLIC_API(size_t)
  4154 JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote);
  4156 /*
  4157  * Create a dependent string, i.e., a string that owns no character storage,
  4158  * but that refers to a slice of another string's chars.  Dependent strings
  4159  * are mutable by definition, so the thread safety comments above apply.
  4160  */
  4161 extern JS_PUBLIC_API(JSString *)
  4162 JS_NewDependentString(JSContext *cx, JS::HandleString str, size_t start,
  4163                       size_t length);
  4165 /*
  4166  * Concatenate two strings, possibly resulting in a rope.
  4167  * See above for thread safety comments.
  4168  */
  4169 extern JS_PUBLIC_API(JSString *)
  4170 JS_ConcatStrings(JSContext *cx, JS::HandleString left, JS::HandleString right);
  4172 /*
  4173  * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
  4174  * the call; on return, *dstlenp contains the number of jschars actually stored.
  4175  * To determine the necessary destination buffer size, make a sizing call that
  4176  * passes nullptr for dst.
  4178  * On errors, the functions report the error. In that case, *dstlenp contains
  4179  * the number of characters or bytes transferred so far.  If cx is nullptr, no
  4180  * error is reported on failure, and the functions simply return false.
  4182  * NB: This function does not store an additional zero byte or jschar after the
  4183  * transcoded string.
  4184  */
  4185 JS_PUBLIC_API(bool)
  4186 JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
  4187                size_t *dstlenp);
  4189 /*
  4190  * A variation on JS_EncodeCharacters where a null terminated string is
  4191  * returned that you are expected to call JS_free on when done.
  4192  */
  4193 JS_PUBLIC_API(char *)
  4194 JS_EncodeString(JSContext *cx, JSString *str);
  4196 /*
  4197  * Same behavior as JS_EncodeString(), but encode into UTF-8 string
  4198  */
  4199 JS_PUBLIC_API(char *)
  4200 JS_EncodeStringToUTF8(JSContext *cx, JS::HandleString str);
  4202 /*
  4203  * Get number of bytes in the string encoding (without accounting for a
  4204  * terminating zero bytes. The function returns (size_t) -1 if the string
  4205  * can not be encoded into bytes and reports an error using cx accordingly.
  4206  */
  4207 JS_PUBLIC_API(size_t)
  4208 JS_GetStringEncodingLength(JSContext *cx, JSString *str);
  4210 /*
  4211  * Encode string into a buffer. The function does not stores an additional
  4212  * zero byte. The function returns (size_t) -1 if the string can not be
  4213  * encoded into bytes with no error reported. Otherwise it returns the number
  4214  * of bytes that are necessary to encode the string. If that exceeds the
  4215  * length parameter, the string will be cut and only length bytes will be
  4216  * written into the buffer.
  4217  */
  4218 JS_PUBLIC_API(size_t)
  4219 JS_EncodeStringToBuffer(JSContext *cx, JSString *str, char *buffer, size_t length);
  4221 class JSAutoByteString
  4223   public:
  4224     JSAutoByteString(JSContext *cx, JSString *str
  4225                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  4226       : mBytes(JS_EncodeString(cx, str))
  4228         JS_ASSERT(cx);
  4229         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4232     JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
  4233       : mBytes(nullptr)
  4235         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4238     ~JSAutoByteString() {
  4239         js_free(mBytes);
  4242     /* Take ownership of the given byte array. */
  4243     void initBytes(char *bytes) {
  4244         JS_ASSERT(!mBytes);
  4245         mBytes = bytes;
  4248     char *encodeLatin1(JSContext *cx, JSString *str) {
  4249         JS_ASSERT(!mBytes);
  4250         JS_ASSERT(cx);
  4251         mBytes = JS_EncodeString(cx, str);
  4252         return mBytes;
  4255     char *encodeLatin1(js::ExclusiveContext *cx, JSString *str);
  4257     char *encodeUtf8(JSContext *cx, JS::HandleString str) {
  4258         JS_ASSERT(!mBytes);
  4259         JS_ASSERT(cx);
  4260         mBytes = JS_EncodeStringToUTF8(cx, str);
  4261         return mBytes;
  4264     void clear() {
  4265         js_free(mBytes);
  4266         mBytes = nullptr;
  4269     char *ptr() const {
  4270         return mBytes;
  4273     bool operator!() const {
  4274         return !mBytes;
  4277     size_t length() const {
  4278         if (!mBytes)
  4279             return 0;
  4280         return strlen(mBytes);
  4283   private:
  4284     char        *mBytes;
  4285     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  4287     /* Copy and assignment are not supported. */
  4288     JSAutoByteString(const JSAutoByteString &another);
  4289     JSAutoByteString &operator=(const JSAutoByteString &another);
  4290 };
  4292 /************************************************************************/
  4293 /*
  4294  * JSON functions
  4295  */
  4296 typedef bool (* JSONWriteCallback)(const jschar *buf, uint32_t len, void *data);
  4298 /*
  4299  * JSON.stringify as specified by ES5.
  4300  */
  4301 JS_PUBLIC_API(bool)
  4302 JS_Stringify(JSContext *cx, JS::MutableHandleValue value, JS::HandleObject replacer,
  4303              JS::HandleValue space, JSONWriteCallback callback, void *data);
  4305 /*
  4306  * JSON.parse as specified by ES5.
  4307  */
  4308 JS_PUBLIC_API(bool)
  4309 JS_ParseJSON(JSContext *cx, const jschar *chars, uint32_t len, JS::MutableHandleValue vp);
  4311 JS_PUBLIC_API(bool)
  4312 JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, JS::HandleValue reviver,
  4313                         JS::MutableHandleValue vp);
  4315 /************************************************************************/
  4317 /*
  4318  * The default locale for the ECMAScript Internationalization API
  4319  * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
  4320  * Note that the Internationalization API encourages clients to
  4321  * specify their own locales.
  4322  * The locale string remains owned by the caller.
  4323  */
  4324 extern JS_PUBLIC_API(bool)
  4325 JS_SetDefaultLocale(JSRuntime *rt, const char *locale);
  4327 /*
  4328  * Returns the default locale for the ECMAScript Internationalization API
  4329  * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
  4330  * Note that the Internationalization API encourages clients to
  4331  * specify their own locales.
  4332  */
  4333 extern JS_PUBLIC_API(const char*)
  4334 JS_GetDefaultLocale(JSRuntime *rt);
  4336 /*
  4337  * Reset the default locale to OS defaults.
  4338  */
  4339 extern JS_PUBLIC_API(void)
  4340 JS_ResetDefaultLocale(JSRuntime *rt);
  4342 /*
  4343  * Locale specific string conversion and error message callbacks.
  4344  */
  4345 struct JSLocaleCallbacks {
  4346     JSLocaleToUpperCase     localeToUpperCase;
  4347     JSLocaleToLowerCase     localeToLowerCase;
  4348     JSLocaleCompare         localeCompare; // not used #if EXPOSE_INTL_API
  4349     JSLocaleToUnicode       localeToUnicode;
  4350     JSErrorCallback         localeGetErrorMessage;
  4351 };
  4353 /*
  4354  * Establish locale callbacks. The pointer must persist as long as the
  4355  * JSRuntime.  Passing nullptr restores the default behaviour.
  4356  */
  4357 extern JS_PUBLIC_API(void)
  4358 JS_SetLocaleCallbacks(JSRuntime *rt, JSLocaleCallbacks *callbacks);
  4360 /*
  4361  * Return the address of the current locale callbacks struct, which may
  4362  * be nullptr.
  4363  */
  4364 extern JS_PUBLIC_API(JSLocaleCallbacks *)
  4365 JS_GetLocaleCallbacks(JSRuntime *rt);
  4367 /************************************************************************/
  4369 /*
  4370  * Error reporting.
  4371  */
  4373 /*
  4374  * Report an exception represented by the sprintf-like conversion of format
  4375  * and its arguments.  This exception message string is passed to a pre-set
  4376  * JSErrorReporter function (set by JS_SetErrorReporter).
  4377  */
  4378 extern JS_PUBLIC_API(void)
  4379 JS_ReportError(JSContext *cx, const char *format, ...);
  4381 /*
  4382  * Use an errorNumber to retrieve the format string, args are char *
  4383  */
  4384 extern JS_PUBLIC_API(void)
  4385 JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
  4386                      void *userRef, const unsigned errorNumber, ...);
  4388 #ifdef va_start
  4389 extern JS_PUBLIC_API(void)
  4390 JS_ReportErrorNumberVA(JSContext *cx, JSErrorCallback errorCallback,
  4391                        void *userRef, const unsigned errorNumber, va_list ap);
  4392 #endif
  4394 /*
  4395  * Use an errorNumber to retrieve the format string, args are jschar *
  4396  */
  4397 extern JS_PUBLIC_API(void)
  4398 JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
  4399                      void *userRef, const unsigned errorNumber, ...);
  4401 extern JS_PUBLIC_API(void)
  4402 JS_ReportErrorNumberUCArray(JSContext *cx, JSErrorCallback errorCallback,
  4403                             void *userRef, const unsigned errorNumber,
  4404                             const jschar **args);
  4406 /*
  4407  * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
  4408  * Return true if there was no error trying to issue the warning, and if the
  4409  * warning was not converted into an error due to the JSOPTION_WERROR option
  4410  * being set, false otherwise.
  4411  */
  4412 extern JS_PUBLIC_API(bool)
  4413 JS_ReportWarning(JSContext *cx, const char *format, ...);
  4415 extern JS_PUBLIC_API(bool)
  4416 JS_ReportErrorFlagsAndNumber(JSContext *cx, unsigned flags,
  4417                              JSErrorCallback errorCallback, void *userRef,
  4418                              const unsigned errorNumber, ...);
  4420 extern JS_PUBLIC_API(bool)
  4421 JS_ReportErrorFlagsAndNumberUC(JSContext *cx, unsigned flags,
  4422                                JSErrorCallback errorCallback, void *userRef,
  4423                                const unsigned errorNumber, ...);
  4425 /*
  4426  * Complain when out of memory.
  4427  */
  4428 extern JS_PUBLIC_API(void)
  4429 JS_ReportOutOfMemory(JSContext *cx);
  4431 /*
  4432  * Complain when an allocation size overflows the maximum supported limit.
  4433  */
  4434 extern JS_PUBLIC_API(void)
  4435 JS_ReportAllocationOverflow(JSContext *cx);
  4437 struct JSErrorReport {
  4438     const char      *filename;      /* source file name, URL, etc., or null */
  4439     JSPrincipals    *originPrincipals; /* see 'originPrincipals' comment above */
  4440     unsigned        lineno;         /* source line number */
  4441     const char      *linebuf;       /* offending source line without final \n */
  4442     const char      *tokenptr;      /* pointer to error token in linebuf */
  4443     const jschar    *uclinebuf;     /* unicode (original) line buffer */
  4444     const jschar    *uctokenptr;    /* unicode (original) token pointer */
  4445     unsigned        flags;          /* error/warning, etc. */
  4446     unsigned        errorNumber;    /* the error number, e.g. see js.msg */
  4447     const jschar    *ucmessage;     /* the (default) error message */
  4448     const jschar    **messageArgs;  /* arguments for the error message */
  4449     int16_t         exnType;        /* One of the JSExnType constants */
  4450     unsigned        column;         /* zero-based column index in line */
  4451 };
  4453 /*
  4454  * JSErrorReport flag values.  These may be freely composed.
  4455  */
  4456 #define JSREPORT_ERROR      0x0     /* pseudo-flag for default case */
  4457 #define JSREPORT_WARNING    0x1     /* reported via JS_ReportWarning */
  4458 #define JSREPORT_EXCEPTION  0x2     /* exception was thrown */
  4459 #define JSREPORT_STRICT     0x4     /* error or warning due to strict option */
  4461 /*
  4462  * This condition is an error in strict mode code, a warning if
  4463  * JS_HAS_STRICT_OPTION(cx), and otherwise should not be reported at
  4464  * all.  We check the strictness of the context's top frame's script;
  4465  * where that isn't appropriate, the caller should do the right checks
  4466  * itself instead of using this flag.
  4467  */
  4468 #define JSREPORT_STRICT_MODE_ERROR 0x8
  4470 /*
  4471  * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
  4472  * has been thrown for this runtime error, and the host should ignore it.
  4473  * Exception-aware hosts should also check for JS_IsExceptionPending if
  4474  * JS_ExecuteScript returns failure, and signal or propagate the exception, as
  4475  * appropriate.
  4476  */
  4477 #define JSREPORT_IS_WARNING(flags)      (((flags) & JSREPORT_WARNING) != 0)
  4478 #define JSREPORT_IS_EXCEPTION(flags)    (((flags) & JSREPORT_EXCEPTION) != 0)
  4479 #define JSREPORT_IS_STRICT(flags)       (((flags) & JSREPORT_STRICT) != 0)
  4480 #define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) &                      \
  4481                                               JSREPORT_STRICT_MODE_ERROR) != 0)
  4482 extern JS_PUBLIC_API(JSErrorReporter)
  4483 JS_GetErrorReporter(JSContext *cx);
  4485 extern JS_PUBLIC_API(JSErrorReporter)
  4486 JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
  4488 namespace JS {
  4490 extern JS_PUBLIC_API(bool)
  4491 CreateTypeError(JSContext *cx, HandleString stack, HandleString fileName,
  4492                 uint32_t lineNumber, uint32_t columnNumber, JSErrorReport *report,
  4493                 HandleString message, MutableHandleValue rval);
  4495 /************************************************************************/
  4497 /*
  4498  * Weak Maps.
  4499  */
  4501 extern JS_PUBLIC_API(JSObject *)
  4502 NewWeakMapObject(JSContext *cx);
  4504 extern JS_PUBLIC_API(bool)
  4505 IsWeakMapObject(JSObject *obj);
  4507 extern JS_PUBLIC_API(bool)
  4508 GetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
  4509                 JS::MutableHandleValue val);
  4511 extern JS_PUBLIC_API(bool)
  4512 SetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
  4513                 JS::HandleValue val);
  4515 } /* namespace JS */
  4517 /*
  4518  * Dates.
  4519  */
  4521 extern JS_PUBLIC_API(JSObject *)
  4522 JS_NewDateObject(JSContext *cx, int year, int mon, int mday, int hour, int min, int sec);
  4524 extern JS_PUBLIC_API(JSObject *)
  4525 JS_NewDateObjectMsec(JSContext *cx, double msec);
  4527 /*
  4528  * Infallible predicate to test whether obj is a date object.
  4529  */
  4530 extern JS_PUBLIC_API(bool)
  4531 JS_ObjectIsDate(JSContext *cx, JS::HandleObject obj);
  4533 /*
  4534  * Clears the cache of calculated local time from each Date object.
  4535  * Call to propagate a system timezone change.
  4536  */
  4537 extern JS_PUBLIC_API(void)
  4538 JS_ClearDateCaches(JSContext *cx);
  4540 /************************************************************************/
  4542 /*
  4543  * Regular Expressions.
  4544  */
  4545 #define JSREG_FOLD      0x01    /* fold uppercase to lowercase */
  4546 #define JSREG_GLOB      0x02    /* global exec, creates array of matches */
  4547 #define JSREG_MULTILINE 0x04    /* treat ^ and $ as begin and end of line */
  4548 #define JSREG_STICKY    0x08    /* only match starting at lastIndex */
  4550 extern JS_PUBLIC_API(JSObject *)
  4551 JS_NewRegExpObject(JSContext *cx, JS::HandleObject obj, char *bytes, size_t length,
  4552                    unsigned flags);
  4554 extern JS_PUBLIC_API(JSObject *)
  4555 JS_NewUCRegExpObject(JSContext *cx, JS::HandleObject obj, jschar *chars, size_t length,
  4556                      unsigned flags);
  4558 extern JS_PUBLIC_API(void)
  4559 JS_SetRegExpInput(JSContext *cx, JS::HandleObject obj, JS::HandleString input,
  4560                   bool multiline);
  4562 extern JS_PUBLIC_API(void)
  4563 JS_ClearRegExpStatics(JSContext *cx, JS::HandleObject obj);
  4565 extern JS_PUBLIC_API(bool)
  4566 JS_ExecuteRegExp(JSContext *cx, JS::HandleObject obj, JS::HandleObject reobj,
  4567                  jschar *chars, size_t length, size_t *indexp, bool test,
  4568                  JS::MutableHandleValue rval);
  4570 /* RegExp interface for clients without a global object. */
  4572 extern JS_PUBLIC_API(JSObject *)
  4573 JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, unsigned flags);
  4575 extern JS_PUBLIC_API(JSObject *)
  4576 JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, unsigned flags);
  4578 extern JS_PUBLIC_API(bool)
  4579 JS_ExecuteRegExpNoStatics(JSContext *cx, JS::HandleObject reobj, jschar *chars, size_t length,
  4580                           size_t *indexp, bool test, JS::MutableHandleValue rval);
  4582 extern JS_PUBLIC_API(bool)
  4583 JS_ObjectIsRegExp(JSContext *cx, JS::HandleObject obj);
  4585 extern JS_PUBLIC_API(unsigned)
  4586 JS_GetRegExpFlags(JSContext *cx, JS::HandleObject obj);
  4588 extern JS_PUBLIC_API(JSString *)
  4589 JS_GetRegExpSource(JSContext *cx, JS::HandleObject obj);
  4591 /************************************************************************/
  4593 extern JS_PUBLIC_API(bool)
  4594 JS_IsExceptionPending(JSContext *cx);
  4596 extern JS_PUBLIC_API(bool)
  4597 JS_GetPendingException(JSContext *cx, JS::MutableHandleValue vp);
  4599 extern JS_PUBLIC_API(void)
  4600 JS_SetPendingException(JSContext *cx, JS::HandleValue v);
  4602 extern JS_PUBLIC_API(void)
  4603 JS_ClearPendingException(JSContext *cx);
  4605 extern JS_PUBLIC_API(bool)
  4606 JS_ReportPendingException(JSContext *cx);
  4608 namespace JS {
  4610 /*
  4611  * Save and later restore the current exception state of a given JSContext.
  4612  * This is useful for implementing behavior in C++ that's like try/catch
  4613  * or try/finally in JS.
  4615  * Typical usage:
  4617  *     bool ok = JS_EvaluateScript(cx, ...);
  4618  *     AutoSaveExceptionState savedExc(cx);
  4619  *     ... cleanup that might re-enter JS ...
  4620  *     return ok;
  4621  */
  4622 class JS_PUBLIC_API(AutoSaveExceptionState)
  4624   private:
  4625     JSContext *context;
  4626     bool wasThrowing;
  4627     RootedValue exceptionValue;
  4629   public:
  4630     /*
  4631      * Take a snapshot of cx's current exception state. Then clear any current
  4632      * pending exception in cx.
  4633      */
  4634     explicit AutoSaveExceptionState(JSContext *cx);
  4636     /*
  4637      * If neither drop() nor restore() was called, restore the exception
  4638      * state only if no exception is currently pending on cx.
  4639      */
  4640     ~AutoSaveExceptionState();
  4642     /*
  4643      * Discard any stored exception state.
  4644      * If this is called, the destructor is a no-op.
  4645      */
  4646     void drop() {
  4647         wasThrowing = false;
  4648         exceptionValue.setUndefined();
  4651     /*
  4652      * Replace cx's exception state with the stored exception state. Then
  4653      * discard the stored exception state. If this is called, the
  4654      * destructor is a no-op.
  4655      */
  4656     void restore();
  4657 };
  4659 } /* namespace JS */
  4661 /* Deprecated API. Use AutoSaveExceptionState instead. */
  4662 extern JS_PUBLIC_API(JSExceptionState *)
  4663 JS_SaveExceptionState(JSContext *cx);
  4665 extern JS_PUBLIC_API(void)
  4666 JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state);
  4668 extern JS_PUBLIC_API(void)
  4669 JS_DropExceptionState(JSContext *cx, JSExceptionState *state);
  4671 /*
  4672  * If the given object is an exception object, the exception will have (or be
  4673  * able to lazily create) an error report struct, and this function will return
  4674  * the address of that struct.  Otherwise, it returns nullptr. The lifetime
  4675  * of the error report struct that might be returned is the same as the
  4676  * lifetime of the exception object.
  4677  */
  4678 extern JS_PUBLIC_API(JSErrorReport *)
  4679 JS_ErrorFromException(JSContext *cx, JS::HandleObject obj);
  4681 /*
  4682  * Throws a StopIteration exception on cx.
  4683  */
  4684 extern JS_PUBLIC_API(bool)
  4685 JS_ThrowStopIteration(JSContext *cx);
  4687 extern JS_PUBLIC_API(bool)
  4688 JS_IsStopIteration(jsval v);
  4690 extern JS_PUBLIC_API(intptr_t)
  4691 JS_GetCurrentThread();
  4693 /*
  4694  * A JS runtime always has an "owner thread". The owner thread is set when the
  4695  * runtime is created (to the current thread) and practically all entry points
  4696  * into the JS engine check that a runtime (or anything contained in the
  4697  * runtime: context, compartment, object, etc) is only touched by its owner
  4698  * thread. Embeddings may check this invariant outside the JS engine by calling
  4699  * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
  4700  * non-debug builds).
  4701  */
  4703 extern JS_PUBLIC_API(void)
  4704 JS_AbortIfWrongThread(JSRuntime *rt);
  4706 /************************************************************************/
  4708 /*
  4709  * A constructor can request that the JS engine create a default new 'this'
  4710  * object of the given class, using the callee to determine parentage and
  4711  * [[Prototype]].
  4712  */
  4713 extern JS_PUBLIC_API(JSObject *)
  4714 JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const JS::CallArgs& args);
  4716 /************************************************************************/
  4718 #ifdef JS_GC_ZEAL
  4719 #define JS_DEFAULT_ZEAL_FREQ 100
  4721 extern JS_PUBLIC_API(void)
  4722 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
  4724 extern JS_PUBLIC_API(void)
  4725 JS_ScheduleGC(JSContext *cx, uint32_t count);
  4726 #endif
  4728 extern JS_PUBLIC_API(void)
  4729 JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled);
  4731 extern JS_PUBLIC_API(void)
  4732 JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled);
  4734 #define JIT_COMPILER_OPTIONS(Register)                                  \
  4735     Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger")    \
  4736     Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger")              \
  4737     Register(ION_ENABLE, "ion.enable")                                  \
  4738     Register(BASELINE_ENABLE, "baseline.enable")                        \
  4739     Register(PARALLEL_COMPILATION_ENABLE, "parallel-compilation.enable")
  4741 typedef enum JSJitCompilerOption {
  4742 #define JIT_COMPILER_DECLARE(key, str) \
  4743     JSJITCOMPILER_ ## key,
  4745     JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
  4746 #undef JIT_COMPILER_DECLARE
  4748     JSJITCOMPILER_NOT_AN_OPTION
  4749 } JSJitCompilerOption;
  4751 extern JS_PUBLIC_API(void)
  4752 JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value);
  4753 extern JS_PUBLIC_API(int)
  4754 JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt);
  4756 /*
  4757  * Convert a uint32_t index into a jsid.
  4758  */
  4759 extern JS_PUBLIC_API(bool)
  4760 JS_IndexToId(JSContext *cx, uint32_t index, JS::MutableHandleId);
  4762 /*
  4763  * Convert chars into a jsid.
  4765  * |chars| may not be an index.
  4766  */
  4767 extern JS_PUBLIC_API(bool)
  4768 JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
  4770 /*
  4771  *  Test if the given string is a valid ECMAScript identifier
  4772  */
  4773 extern JS_PUBLIC_API(bool)
  4774 JS_IsIdentifier(JSContext *cx, JS::HandleString str, bool *isIdentifier);
  4776 namespace JS {
  4778 /*
  4779  * AutoFilename encapsulates a pointer to a C-string and keeps the C-string
  4780  * alive for as long as the associated AutoFilename object is alive.
  4781  */
  4782 class MOZ_STACK_CLASS JS_PUBLIC_API(AutoFilename)
  4784     void *scriptSource_;
  4786     AutoFilename(const AutoFilename &) MOZ_DELETE;
  4787     void operator=(const AutoFilename &) MOZ_DELETE;
  4789   public:
  4790     AutoFilename() : scriptSource_(nullptr) {}
  4791     ~AutoFilename() { reset(nullptr); }
  4793     const char *get() const;
  4795     void reset(void *newScriptSource);
  4796 };
  4798 /*
  4799  * Return the current filename and line number of the most currently running
  4800  * frame. Returns true if a scripted frame was found, false otherwise.
  4802  * If a the embedding has hidden the scripted caller for the topmost activation
  4803  * record, this will also return false.
  4804  */
  4805 extern JS_PUBLIC_API(bool)
  4806 DescribeScriptedCaller(JSContext *cx, AutoFilename *filename = nullptr,
  4807                        unsigned *lineno = nullptr);
  4809 extern JS_PUBLIC_API(JSObject *)
  4810 GetScriptedCallerGlobal(JSContext *cx);
  4812 /*
  4813  * Informs the JS engine that the scripted caller should be hidden. This can be
  4814  * used by the embedding to maintain an override of the scripted caller in its
  4815  * calculations, by hiding the scripted caller in the JS engine and pushing data
  4816  * onto a separate stack, which it inspects when DescribeScriptedCaller returns
  4817  * null.
  4819  * We maintain a counter on each activation record. Add() increments the counter
  4820  * of the topmost activation, and Remove() decrements it. The count may never
  4821  * drop below zero, and must always be exactly zero when the activation is
  4822  * popped from the stack.
  4823  */
  4824 extern JS_PUBLIC_API(void)
  4825 HideScriptedCaller(JSContext *cx);
  4827 extern JS_PUBLIC_API(void)
  4828 UnhideScriptedCaller(JSContext *cx);
  4830 class AutoHideScriptedCaller
  4832   public:
  4833     AutoHideScriptedCaller(JSContext *cx
  4834                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
  4835       : mContext(cx)
  4837         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
  4838         HideScriptedCaller(mContext);
  4840     ~AutoHideScriptedCaller() {
  4841         UnhideScriptedCaller(mContext);
  4844   protected:
  4845     JSContext *mContext;
  4846     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
  4847 };
  4849 } /* namespace JS */
  4851 /*
  4852  * Encode/Decode interpreted scripts and functions to/from memory.
  4853  */
  4855 extern JS_PUBLIC_API(void *)
  4856 JS_EncodeScript(JSContext *cx, JS::HandleScript script, uint32_t *lengthp);
  4858 extern JS_PUBLIC_API(void *)
  4859 JS_EncodeInterpretedFunction(JSContext *cx, JS::HandleObject funobj, uint32_t *lengthp);
  4861 extern JS_PUBLIC_API(JSScript *)
  4862 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length, JSPrincipals *originPrincipals);
  4864 extern JS_PUBLIC_API(JSObject *)
  4865 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
  4866                              JSPrincipals *originPrincipals);
  4868 namespace JS {
  4870 /*
  4871  * This callback represents a request by the JS engine to open for reading the
  4872  * existing cache entry for the given global and char range that may contain a
  4873  * module. If a cache entry exists, the callback shall return 'true' and return
  4874  * the size, base address and an opaque file handle as outparams. If the
  4875  * callback returns 'true', the JS engine guarantees a call to
  4876  * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
  4877  * handle.
  4878  */
  4879 typedef bool
  4880 (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const jschar *begin, const jschar *limit,
  4881                                  size_t *size, const uint8_t **memory, intptr_t *handle);
  4882 typedef void
  4883 (* CloseAsmJSCacheEntryForReadOp)(HandleObject global, size_t size, const uint8_t *memory,
  4884                                   intptr_t handle);
  4886 /*
  4887  * This callback represents a request by the JS engine to open for writing a
  4888  * cache entry of the given size for the given global and char range containing
  4889  * the just-compiled module. If cache entry space is available, the callback
  4890  * shall return 'true' and return the base address and an opaque file handle as
  4891  * outparams. If the callback returns 'true', the JS engine guarantees a call
  4892  * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
  4893  * handle.
  4895  * If 'installed' is true, then the cache entry is associated with a permanently
  4896  * installed JS file (e.g., in a packaged webapp). This information allows the
  4897  * embedding to store the cache entry in a installed location associated with
  4898  * the principal of 'global' where it will not be evicted until the associated
  4899  * installed JS file is removed.
  4900  */
  4901 typedef bool
  4902 (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
  4903                                   const jschar *begin, const jschar *end,
  4904                                   size_t size, uint8_t **memory, intptr_t *handle);
  4905 typedef void
  4906 (* CloseAsmJSCacheEntryForWriteOp)(HandleObject global, size_t size, uint8_t *memory,
  4907                                    intptr_t handle);
  4909 typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
  4911 // Return the buildId (represented as a sequence of characters) associated with
  4912 // the currently-executing build. If the JS engine is embedded such that a
  4913 // single cache entry can be observed by different compiled versions of the JS
  4914 // engine, it is critical that the buildId shall change for each new build of
  4915 // the JS engine.
  4917 typedef bool
  4918 (* BuildIdOp)(BuildIdCharVector *buildId);
  4920 struct AsmJSCacheOps
  4922     OpenAsmJSCacheEntryForReadOp openEntryForRead;
  4923     CloseAsmJSCacheEntryForReadOp closeEntryForRead;
  4924     OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
  4925     CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
  4926     BuildIdOp buildId;
  4927 };
  4929 extern JS_PUBLIC_API(void)
  4930 SetAsmJSCacheOps(JSRuntime *rt, const AsmJSCacheOps *callbacks);
  4932 /*
  4933  * Convenience class for imitating a JS level for-of loop. Typical usage:
  4935  *     ForOfIterator it(cx);
  4936  *     if (!it.init(iterable))
  4937  *       return false;
  4938  *     RootedValue val(cx);
  4939  *     while (true) {
  4940  *       bool done;
  4941  *       if (!it.next(&val, &done))
  4942  *         return false;
  4943  *       if (done)
  4944  *         break;
  4945  *       if (!DoStuff(cx, val))
  4946  *         return false;
  4947  *     }
  4948  */
  4949 class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
  4950   protected:
  4951     JSContext *cx_;
  4952     /*
  4953      * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
  4954      * to optimize iteration across arrays.
  4956      *  Case 1: Regular Iteration
  4957      *      iterator - pointer to the iterator object.
  4958      *      index - fixed to NOT_ARRAY (== UINT32_MAX)
  4960      *  Case 2: Optimized Array Iteration
  4961      *      iterator - pointer to the array object.
  4962      *      index - current position in array.
  4964      * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
  4965      */
  4966     JS::RootedObject iterator;
  4967     uint32_t index;
  4969     static const uint32_t NOT_ARRAY = UINT32_MAX;
  4971     ForOfIterator(const ForOfIterator &) MOZ_DELETE;
  4972     ForOfIterator &operator=(const ForOfIterator &) MOZ_DELETE;
  4974   public:
  4975     ForOfIterator(JSContext *cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
  4977     enum NonIterableBehavior {
  4978         ThrowOnNonIterable,
  4979         AllowNonIterable
  4980     };
  4982     /*
  4983      * Initialize the iterator.  If AllowNonIterable is passed then if iterable
  4984      * does not have a callable @@iterator init() will just return true instead
  4985      * of throwing.  Callers should then check valueIsIterable() before
  4986      * continuing with the iteration.
  4987      */
  4988     bool init(JS::HandleValue iterable,
  4989               NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
  4991     /*
  4992      * Get the next value from the iterator.  If false *done is true
  4993      * after this call, do not examine val.
  4994      */
  4995     bool next(JS::MutableHandleValue val, bool *done);
  4997     /*
  4998      * If initialized with throwOnNonCallable = false, check whether
  4999      * the value is iterable.
  5000      */
  5001     bool valueIsIterable() const {
  5002         return iterator;
  5005   private:
  5006     inline bool nextFromOptimizedArray(MutableHandleValue val, bool *done);
  5007     bool materializeArrayIterator();
  5008 };
  5011 /*
  5012  * If a large allocation fails, the JS engine may call the large-allocation-
  5013  * failure callback, if set, to allow the embedding to flush caches, possibly
  5014  * perform shrinking GCs, etc. to make some room so that the allocation will
  5015  * succeed if retried. After the callback returns, the JS engine will try to
  5016  * allocate again and may be succesful.
  5017  */
  5019 typedef void
  5020 (* LargeAllocationFailureCallback)();
  5022 extern JS_PUBLIC_API(void)
  5023 SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc);
  5025 /*
  5026  * Unlike the error reporter, which is only called if the exception for an OOM
  5027  * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
  5028  * at the OOM site to allow the embedding to capture the current state of heap
  5029  * allocation before anything is freed. If the large-allocation-failure callback
  5030  * is called at all (not all allocation sites call the large-allocation-failure
  5031  * callback on failure), it is called before the out-of-memory callback; the
  5032  * out-of-memory callback is only called if the allocation still fails after the
  5033  * large-allocation-failure callback has returned.
  5034  */
  5036 typedef void
  5037 (* OutOfMemoryCallback)(JSContext *cx);
  5039 extern JS_PUBLIC_API(void)
  5040 SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb);
  5042 } /* namespace JS */
  5044 #endif /* jsapi_h */

mercurial