LCOV - code coverage report
Current view: top level - js/src - jsapi.h (source / functions) Hit Total Coverage
Test: output.info Lines: 557 672 82.9 %
Date: 2017-07-14 16:53:18 Functions: 282 368 76.6 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       6             : 
       7             : /* JavaScript API. */
       8             : 
       9             : #ifndef jsapi_h
      10             : #define jsapi_h
      11             : 
      12             : #include "mozilla/AlreadyAddRefed.h"
      13             : #include "mozilla/FloatingPoint.h"
      14             : #include "mozilla/MemoryReporting.h"
      15             : #include "mozilla/Range.h"
      16             : #include "mozilla/RangedPtr.h"
      17             : #include "mozilla/RefPtr.h"
      18             : #include "mozilla/Variant.h"
      19             : 
      20             : #include <iterator>
      21             : #include <stdarg.h>
      22             : #include <stddef.h>
      23             : #include <stdint.h>
      24             : #include <stdio.h>
      25             : 
      26             : #include "jsalloc.h"
      27             : #include "jspubtd.h"
      28             : 
      29             : #include "js/CallArgs.h"
      30             : #include "js/CharacterEncoding.h"
      31             : #include "js/Class.h"
      32             : #include "js/GCVector.h"
      33             : #include "js/HashTable.h"
      34             : #include "js/Id.h"
      35             : #include "js/Principals.h"
      36             : #include "js/Realm.h"
      37             : #include "js/RefCounted.h"
      38             : #include "js/RootingAPI.h"
      39             : #include "js/TracingAPI.h"
      40             : #include "js/UniquePtr.h"
      41             : #include "js/Utility.h"
      42             : #include "js/Value.h"
      43             : #include "js/Vector.h"
      44             : 
      45             : /************************************************************************/
      46             : 
      47             : namespace JS {
      48             : 
      49             : class TwoByteChars;
      50             : 
      51             : #ifdef JS_DEBUG
      52             : 
      53             : class JS_PUBLIC_API(AutoCheckRequestDepth)
      54             : {
      55             :     JSContext* cx;
      56             :   public:
      57             :     explicit AutoCheckRequestDepth(JSContext* cx);
      58             :     ~AutoCheckRequestDepth();
      59             : };
      60             : 
      61             : # define CHECK_REQUEST(cx) \
      62             :     JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
      63             : 
      64             : #else
      65             : 
      66             : # define CHECK_REQUEST(cx) \
      67             :     ((void) 0)
      68             : 
      69             : #endif /* JS_DEBUG */
      70             : 
      71             : /** AutoValueArray roots an internal fixed-size array of Values. */
      72             : template <size_t N>
      73        8329 : class MOZ_RAII AutoValueArray : public AutoGCRooter
      74             : {
      75             :     const size_t length_;
      76             :     Value elements_[N];
      77             : 
      78             :   public:
      79        8330 :     explicit AutoValueArray(JSContext* cx
      80             :                             MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
      81        8330 :       : AutoGCRooter(cx, VALARRAY), length_(N)
      82             :     {
      83             :         /* Always initialize in case we GC before assignment. */
      84        8330 :         mozilla::PodArrayZero(elements_);
      85        8330 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
      86        8330 :     }
      87             : 
      88          18 :     unsigned length() const { return length_; }
      89           0 :     const Value* begin() const { return elements_; }
      90        8328 :     Value* begin() { return elements_; }
      91             : 
      92             :     HandleValue operator[](unsigned i) const {
      93             :         MOZ_ASSERT(i < N);
      94             :         return HandleValue::fromMarkedLocation(&elements_[i]);
      95             :     }
      96        1042 :     MutableHandleValue operator[](unsigned i) {
      97        1042 :         MOZ_ASSERT(i < N);
      98        1042 :         return MutableHandleValue::fromMarkedLocation(&elements_[i]);
      99             :     }
     100             : 
     101             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     102             : };
     103             : 
     104             : template<class T>
     105           6 : class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter
     106             : {
     107             :     typedef js::Vector<T, 8> VectorImpl;
     108             :     VectorImpl vector;
     109             : 
     110             :   public:
     111           6 :     explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag
     112             :                               MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     113           6 :       : AutoGCRooter(cx, tag), vector(cx)
     114             :     {
     115           6 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     116           6 :     }
     117             : 
     118             :     typedef T ElementType;
     119             :     typedef typename VectorImpl::Range Range;
     120             : 
     121             :     size_t length() const { return vector.length(); }
     122             :     bool empty() const { return vector.empty(); }
     123             : 
     124           0 :     MOZ_MUST_USE bool append(const T& v) { return vector.append(v); }
     125             :     MOZ_MUST_USE bool appendN(const T& v, size_t len) { return vector.appendN(v, len); }
     126             :     MOZ_MUST_USE bool append(const T* ptr, size_t len) { return vector.append(ptr, len); }
     127             :     MOZ_MUST_USE bool appendAll(const AutoVectorRooterBase<T>& other) {
     128             :         return vector.appendAll(other.vector);
     129             :     }
     130             : 
     131             :     MOZ_MUST_USE bool insert(T* p, const T& val) { return vector.insert(p, val); }
     132             : 
     133             :     /* For use when space has already been reserved. */
     134          10 :     void infallibleAppend(const T& v) { vector.infallibleAppend(v); }
     135             : 
     136             :     void popBack() { vector.popBack(); }
     137             :     T popCopy() { return vector.popCopy(); }
     138             : 
     139             :     MOZ_MUST_USE bool growBy(size_t inc) {
     140             :         size_t oldLength = vector.length();
     141             :         if (!vector.growByUninitialized(inc))
     142             :             return false;
     143             :         makeRangeGCSafe(oldLength);
     144             :         return true;
     145             :     }
     146             : 
     147             :     MOZ_MUST_USE bool resize(size_t newLength) {
     148             :         size_t oldLength = vector.length();
     149             :         if (newLength <= oldLength) {
     150             :             vector.shrinkBy(oldLength - newLength);
     151             :             return true;
     152             :         }
     153             :         if (!vector.growByUninitialized(newLength - oldLength))
     154             :             return false;
     155             :         makeRangeGCSafe(oldLength);
     156             :         return true;
     157             :     }
     158             : 
     159             :     void clear() { vector.clear(); }
     160             : 
     161           3 :     MOZ_MUST_USE bool reserve(size_t newLength) {
     162           3 :         return vector.reserve(newLength);
     163             :     }
     164             : 
     165             :     JS::MutableHandle<T> operator[](size_t i) {
     166             :         return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
     167             :     }
     168             :     JS::Handle<T> operator[](size_t i) const {
     169             :         return JS::Handle<T>::fromMarkedLocation(&vector[i]);
     170             :     }
     171             : 
     172             :     const T* begin() const { return vector.begin(); }
     173           6 :     T* begin() { return vector.begin(); }
     174             : 
     175             :     const T* end() const { return vector.end(); }
     176           6 :     T* end() { return vector.end(); }
     177             : 
     178             :     Range all() { return vector.all(); }
     179             : 
     180             :     const T& back() const { return vector.back(); }
     181             : 
     182             :     friend void AutoGCRooter::trace(JSTracer* trc);
     183             : 
     184             :   private:
     185             :     void makeRangeGCSafe(size_t oldLength) {
     186             :         T* t = vector.begin() + oldLength;
     187             :         for (size_t i = oldLength; i < vector.length(); ++i, ++t)
     188             :             memset(t, 0, sizeof(T));
     189             :     }
     190             : 
     191             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     192             : };
     193             : 
     194             : template <typename T>
     195             : class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase<T>
     196             : {
     197             :   public:
     198             :     explicit AutoVectorRooter(JSContext* cx
     199             :                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     200             :         : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
     201             :     {
     202             :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     203             :     }
     204             : 
     205             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     206             : };
     207             : 
     208       10760 : class AutoValueVector : public Rooted<GCVector<Value, 8>> {
     209             :     using Vec = GCVector<Value, 8>;
     210             :     using Base = Rooted<Vec>;
     211             :   public:
     212       10765 :     explicit AutoValueVector(JSContext* cx) : Base(cx, Vec(cx)) {}
     213             : };
     214             : 
     215        2873 : class AutoIdVector : public Rooted<GCVector<jsid, 8>> {
     216             :     using Vec = GCVector<jsid, 8>;
     217             :     using Base = Rooted<Vec>;
     218             :   public:
     219        2873 :     explicit AutoIdVector(JSContext* cx) : Base(cx, Vec(cx)) {}
     220             : 
     221           0 :     bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); }
     222             : };
     223             : 
     224        9979 : class AutoObjectVector : public Rooted<GCVector<JSObject*, 8>> {
     225             :     using Vec = GCVector<JSObject*, 8>;
     226             :     using Base = Rooted<Vec>;
     227             :   public:
     228        9979 :     explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {}
     229             : };
     230             : 
     231             : using ValueVector = JS::GCVector<JS::Value>;
     232             : using IdVector = JS::GCVector<jsid>;
     233             : using ScriptVector = JS::GCVector<JSScript*>;
     234             : using StringVector = JS::GCVector<JSString*>;
     235             : 
     236             : template<class Key, class Value>
     237             : class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter
     238             : {
     239             :   private:
     240             :     typedef js::HashMap<Key, Value> HashMapImpl;
     241             : 
     242             :   public:
     243             :     explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag
     244             :                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     245             :       : AutoGCRooter(cx, tag), map(cx)
     246             :     {
     247             :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     248             :     }
     249             : 
     250             :     typedef Key KeyType;
     251             :     typedef Value ValueType;
     252             :     typedef typename HashMapImpl::Entry Entry;
     253             :     typedef typename HashMapImpl::Lookup Lookup;
     254             :     typedef typename HashMapImpl::Ptr Ptr;
     255             :     typedef typename HashMapImpl::AddPtr AddPtr;
     256             : 
     257             :     bool init(uint32_t len = 16) {
     258             :         return map.init(len);
     259             :     }
     260             :     bool initialized() const {
     261             :         return map.initialized();
     262             :     }
     263             :     Ptr lookup(const Lookup& l) const {
     264             :         return map.lookup(l);
     265             :     }
     266             :     void remove(Ptr p) {
     267             :         map.remove(p);
     268             :     }
     269             :     AddPtr lookupForAdd(const Lookup& l) const {
     270             :         return map.lookupForAdd(l);
     271             :     }
     272             : 
     273             :     template<typename KeyInput, typename ValueInput>
     274             :     bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) {
     275             :         return map.add(p, k, v);
     276             :     }
     277             : 
     278             :     bool add(AddPtr& p, const Key& k) {
     279             :         return map.add(p, k);
     280             :     }
     281             : 
     282             :     template<typename KeyInput, typename ValueInput>
     283             :     bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
     284             :         return map.relookupOrAdd(p, k, v);
     285             :     }
     286             : 
     287             :     typedef typename HashMapImpl::Range Range;
     288             :     Range all() const {
     289             :         return map.all();
     290             :     }
     291             : 
     292             :     typedef typename HashMapImpl::Enum Enum;
     293             : 
     294             :     void clear() {
     295             :         map.clear();
     296             :     }
     297             : 
     298             :     void finish() {
     299             :         map.finish();
     300             :     }
     301             : 
     302             :     bool empty() const {
     303             :         return map.empty();
     304             :     }
     305             : 
     306             :     uint32_t count() const {
     307             :         return map.count();
     308             :     }
     309             : 
     310             :     size_t capacity() const {
     311             :         return map.capacity();
     312             :     }
     313             : 
     314             :     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
     315             :         return map.sizeOfExcludingThis(mallocSizeOf);
     316             :     }
     317             :     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
     318             :         return map.sizeOfIncludingThis(mallocSizeOf);
     319             :     }
     320             : 
     321             :     /************************************************** Shorthand operations */
     322             : 
     323             :     bool has(const Lookup& l) const {
     324             :         return map.has(l);
     325             :     }
     326             : 
     327             :     template<typename KeyInput, typename ValueInput>
     328             :     bool put(const KeyInput& k, const ValueInput& v) {
     329             :         return map.put(k, v);
     330             :     }
     331             : 
     332             :     template<typename KeyInput, typename ValueInput>
     333             :     bool putNew(const KeyInput& k, const ValueInput& v) {
     334             :         return map.putNew(k, v);
     335             :     }
     336             : 
     337             :     Ptr lookupWithDefault(const Key& k, const Value& defaultValue) {
     338             :         return map.lookupWithDefault(k, defaultValue);
     339             :     }
     340             : 
     341             :     void remove(const Lookup& l) {
     342             :         map.remove(l);
     343             :     }
     344             : 
     345             :     friend void AutoGCRooter::trace(JSTracer* trc);
     346             : 
     347             :   private:
     348             :     AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete;
     349             :     AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete;
     350             : 
     351             :     HashMapImpl map;
     352             : 
     353             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     354             : };
     355             : 
     356             : template<class T>
     357             : class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter
     358             : {
     359             :   private:
     360             :     typedef js::HashSet<T> HashSetImpl;
     361             : 
     362             :   public:
     363             :     explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag
     364             :                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     365             :       : AutoGCRooter(cx, tag), set(cx)
     366             :     {
     367             :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     368             :     }
     369             : 
     370             :     typedef typename HashSetImpl::Lookup Lookup;
     371             :     typedef typename HashSetImpl::Ptr Ptr;
     372             :     typedef typename HashSetImpl::AddPtr AddPtr;
     373             : 
     374             :     bool init(uint32_t len = 16) {
     375             :         return set.init(len);
     376             :     }
     377             :     bool initialized() const {
     378             :         return set.initialized();
     379             :     }
     380             :     Ptr lookup(const Lookup& l) const {
     381             :         return set.lookup(l);
     382             :     }
     383             :     void remove(Ptr p) {
     384             :         set.remove(p);
     385             :     }
     386             :     AddPtr lookupForAdd(const Lookup& l) const {
     387             :         return set.lookupForAdd(l);
     388             :     }
     389             : 
     390             :     bool add(AddPtr& p, const T& t) {
     391             :         return set.add(p, t);
     392             :     }
     393             : 
     394             :     bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) {
     395             :         return set.relookupOrAdd(p, l, t);
     396             :     }
     397             : 
     398             :     typedef typename HashSetImpl::Range Range;
     399             :     Range all() const {
     400             :         return set.all();
     401             :     }
     402             : 
     403             :     typedef typename HashSetImpl::Enum Enum;
     404             : 
     405             :     void clear() {
     406             :         set.clear();
     407             :     }
     408             : 
     409             :     void finish() {
     410             :         set.finish();
     411             :     }
     412             : 
     413             :     bool empty() const {
     414             :         return set.empty();
     415             :     }
     416             : 
     417             :     uint32_t count() const {
     418             :         return set.count();
     419             :     }
     420             : 
     421             :     size_t capacity() const {
     422             :         return set.capacity();
     423             :     }
     424             : 
     425             :     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
     426             :         return set.sizeOfExcludingThis(mallocSizeOf);
     427             :     }
     428             :     size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
     429             :         return set.sizeOfIncludingThis(mallocSizeOf);
     430             :     }
     431             : 
     432             :     /************************************************** Shorthand operations */
     433             : 
     434             :     bool has(const Lookup& l) const {
     435             :         return set.has(l);
     436             :     }
     437             : 
     438             :     bool put(const T& t) {
     439             :         return set.put(t);
     440             :     }
     441             : 
     442             :     bool putNew(const T& t) {
     443             :         return set.putNew(t);
     444             :     }
     445             : 
     446             :     void remove(const Lookup& l) {
     447             :         set.remove(l);
     448             :     }
     449             : 
     450             :     friend void AutoGCRooter::trace(JSTracer* trc);
     451             : 
     452             :   private:
     453             :     AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete;
     454             :     AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete;
     455             : 
     456             :     HashSetImpl set;
     457             : 
     458             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     459             : };
     460             : 
     461             : /**
     462             :  * Custom rooting behavior for internal and external clients.
     463             :  */
     464             : class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
     465             : {
     466             :   public:
     467             :     template <typename CX>
     468       52023 :     explicit CustomAutoRooter(const CX& cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     469       52023 :       : AutoGCRooter(cx, CUSTOM)
     470             :     {
     471       52023 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     472       52023 :     }
     473             : 
     474             :     friend void AutoGCRooter::trace(JSTracer* trc);
     475             : 
     476             :   protected:
     477       52024 :     virtual ~CustomAutoRooter() {}
     478             : 
     479             :     /** Supplied by derived class to trace roots. */
     480             :     virtual void trace(JSTracer* trc) = 0;
     481             : 
     482             :   private:
     483             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     484             : };
     485             : 
     486             : /** A handle to an array of rooted values. */
     487             : class HandleValueArray
     488             : {
     489             :     const size_t length_;
     490             :     const Value * const elements_;
     491             : 
     492        4509 :     HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {}
     493             : 
     494             :   public:
     495         777 :     explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
     496             : 
     497         685 :     MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values)
     498         685 :       : length_(values.length()), elements_(values.begin()) {}
     499             : 
     500             :     template <size_t N>
     501           0 :     MOZ_IMPLICIT HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
     502             : 
     503             :     /** CallArgs must already be rooted somewhere up the stack. */
     504          27 :     MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
     505             : 
     506             :     /** Use with care! Only call this if the data is guaranteed to be marked. */
     507        3981 :     static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) {
     508        3981 :         return HandleValueArray(len, elements);
     509             :     }
     510             : 
     511          59 :     static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
     512          59 :         MOZ_ASSERT(startIndex + len <= values.length());
     513          59 :         return HandleValueArray(len, values.begin() + startIndex);
     514             :     }
     515             : 
     516         463 :     static HandleValueArray empty() {
     517         463 :         return HandleValueArray(0, nullptr);
     518             :     }
     519             : 
     520        6127 :     size_t length() const { return length_; }
     521         107 :     const Value* begin() const { return elements_; }
     522             : 
     523        5346 :     HandleValue operator[](size_t i) const {
     524        5346 :         MOZ_ASSERT(i < length_);
     525        5346 :         return HandleValue::fromMarkedLocation(&elements_[i]);
     526             :     }
     527             : };
     528             : 
     529             : }  /* namespace JS */
     530             : 
     531             : /************************************************************************/
     532             : 
     533             : struct JSFreeOp {
     534             :   protected:
     535             :     JSRuntime*  runtime_;
     536             : 
     537           4 :     explicit JSFreeOp(JSRuntime* rt)
     538           4 :       : runtime_(rt) { }
     539             : 
     540             :   public:
     541           9 :     JSRuntime* runtime() const {
     542           9 :         MOZ_ASSERT(runtime_);
     543           9 :         return runtime_;
     544             :     }
     545             : };
     546             : 
     547             : /* Callbacks and their arguments. */
     548             : 
     549             : /************************************************************************/
     550             : 
     551             : typedef enum JSGCStatus {
     552             :     JSGC_BEGIN,
     553             :     JSGC_END
     554             : } JSGCStatus;
     555             : 
     556             : typedef void
     557             : (* JSGCCallback)(JSContext* cx, JSGCStatus status, void* data);
     558             : 
     559             : typedef void
     560             : (* JSObjectsTenuredCallback)(JSContext* cx, void* data);
     561             : 
     562             : typedef enum JSFinalizeStatus {
     563             :     /**
     564             :      * Called when preparing to sweep a group of zones, before anything has been
     565             :      * swept.  The collector will not yield to the mutator before calling the
     566             :      * callback with JSFINALIZE_GROUP_START status.
     567             :      */
     568             :     JSFINALIZE_GROUP_PREPARE,
     569             : 
     570             :     /**
     571             :      * Called after preparing to sweep a group of zones. Weak references to
     572             :      * unmarked things have been removed at this point, but no GC things have
     573             :      * been swept. The collector may yield to the mutator after this point.
     574             :      */
     575             :     JSFINALIZE_GROUP_START,
     576             : 
     577             :     /**
     578             :      * Called after sweeping a group of zones. All dead GC things have been
     579             :      * swept at this point.
     580             :      */
     581             :     JSFINALIZE_GROUP_END,
     582             : 
     583             :     /**
     584             :      * Called at the end of collection when everything has been swept.
     585             :      */
     586             :     JSFINALIZE_COLLECTION_END
     587             : } JSFinalizeStatus;
     588             : 
     589             : typedef void
     590             : (* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isZoneGC, void* data);
     591             : 
     592             : typedef void
     593             : (* JSWeakPointerZonesCallback)(JSContext* cx, void* data);
     594             : 
     595             : typedef void
     596             : (* JSWeakPointerCompartmentCallback)(JSContext* cx, JSCompartment* comp, void* data);
     597             : 
     598             : typedef bool
     599             : (* JSInterruptCallback)(JSContext* cx);
     600             : 
     601             : typedef JSObject*
     602             : (* JSGetIncumbentGlobalCallback)(JSContext* cx);
     603             : 
     604             : typedef bool
     605             : (* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job,
     606             :                                 JS::HandleObject allocationSite, JS::HandleObject incumbentGlobal,
     607             :                                 void* data);
     608             : 
     609             : enum class PromiseRejectionHandlingState {
     610             :     Unhandled,
     611             :     Handled
     612             : };
     613             : 
     614             : typedef void
     615             : (* JSPromiseRejectionTrackerCallback)(JSContext* cx, JS::HandleObject promise,
     616             :                                       PromiseRejectionHandlingState state, void* data);
     617             : 
     618             : typedef void
     619             : (* JSProcessPromiseCallback)(JSContext* cx, JS::HandleObject promise);
     620             : 
     621             : /**
     622             :  * Possible exception types. These types are part of a JSErrorFormatString
     623             :  * structure. They define which error to throw in case of a runtime error.
     624             :  *
     625             :  * JSEXN_WARN is used for warnings in js.msg files (for instance because we
     626             :  * don't want to prepend 'Error:' to warning messages). This value can go away
     627             :  * if we ever decide to use an entirely separate mechanism for warnings.
     628             :  */
     629             : typedef enum JSExnType {
     630             :     JSEXN_ERR,
     631             :     JSEXN_FIRST = JSEXN_ERR,
     632             :         JSEXN_INTERNALERR,
     633             :         JSEXN_EVALERR,
     634             :         JSEXN_RANGEERR,
     635             :         JSEXN_REFERENCEERR,
     636             :         JSEXN_SYNTAXERR,
     637             :         JSEXN_TYPEERR,
     638             :         JSEXN_URIERR,
     639             :         JSEXN_DEBUGGEEWOULDRUN,
     640             :         JSEXN_WASMCOMPILEERROR,
     641             :         JSEXN_WASMLINKERROR,
     642             :         JSEXN_WASMRUNTIMEERROR,
     643             :     JSEXN_ERROR_LIMIT,
     644             :     JSEXN_WARN = JSEXN_ERROR_LIMIT,
     645             :     JSEXN_NOTE,
     646             :     JSEXN_LIMIT
     647             : } JSExnType;
     648             : 
     649             : struct JSErrorFormatString {
     650             :      /** The error message name in ASCII. */
     651             :     const char* name;
     652             : 
     653             :     /** The error format string in ASCII. */
     654             :     const char* format;
     655             : 
     656             :     /** The number of arguments to expand in the formatted error message. */
     657             :     uint16_t argCount;
     658             : 
     659             :     /** One of the JSExnType constants above. */
     660             :     int16_t exnType;
     661             : };
     662             : 
     663             : typedef const JSErrorFormatString*
     664             : (* JSErrorCallback)(void* userRef, const unsigned errorNumber);
     665             : 
     666             : typedef bool
     667             : (* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
     668             : 
     669             : typedef bool
     670             : (* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
     671             : 
     672             : typedef bool
     673             : (* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2,
     674             :                     JS::MutableHandleValue rval);
     675             : 
     676             : typedef bool
     677             : (* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval);
     678             : 
     679             : /**
     680             :  * Callback used to ask the embedding for the cross compartment wrapper handler
     681             :  * that implements the desired prolicy for this kind of object in the
     682             :  * destination compartment. |obj| is the object to be wrapped. If |existing| is
     683             :  * non-nullptr, it will point to an existing wrapper object that should be
     684             :  * re-used if possible. |existing| is guaranteed to be a cross-compartment
     685             :  * wrapper with a lazily-defined prototype and the correct global. It is
     686             :  * guaranteed not to wrap a function.
     687             :  */
     688             : typedef JSObject*
     689             : (* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj);
     690             : 
     691             : /**
     692             :  * Callback used by the wrap hook to ask the embedding to prepare an object
     693             :  * for wrapping in a context. This might include unwrapping other wrappers
     694             :  * or even finding a more suitable object for the new compartment.
     695             :  */
     696             : typedef void
     697             : (* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
     698             :                       JS::HandleObject objectPassedToWrap,
     699             :                       JS::MutableHandleObject retObj);
     700             : 
     701             : struct JSWrapObjectCallbacks
     702             : {
     703             :     JSWrapObjectCallback wrap;
     704             :     JSPreWrapCallback preWrap;
     705             : };
     706             : 
     707             : typedef void
     708             : (* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment);
     709             : 
     710             : typedef size_t
     711             : (* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf,
     712             :                                              JSCompartment* compartment);
     713             : 
     714             : typedef void
     715             : (* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment,
     716             :                               char* buf, size_t bufsize);
     717             : 
     718             : /**
     719             :  * Callback used by memory reporting to ask the embedder how much memory an
     720             :  * external string is keeping alive.  The embedder is expected to return a value
     721             :  * that corresponds to the size of the allocation that will be released by the
     722             :  * JSStringFinalizer passed to JS_NewExternalString for this string.
     723             :  *
     724             :  * Implementations of this callback MUST NOT do anything that can cause GC.
     725             :  */
     726             : using JSExternalStringSizeofCallback =
     727             :     size_t (*)(JSString* str, mozilla::MallocSizeOf mallocSizeOf);
     728             : 
     729             : /************************************************************************/
     730             : 
     731             : static MOZ_ALWAYS_INLINE JS::Value
     732        3423 : JS_NumberValue(double d)
     733             : {
     734             :     int32_t i;
     735        3423 :     d = JS::CanonicalizeNaN(d);
     736        3423 :     if (mozilla::NumberIsInt32(d, &i))
     737        3391 :         return JS::Int32Value(i);
     738          32 :     return JS::DoubleValue(d);
     739             : }
     740             : 
     741             : /************************************************************************/
     742             : 
     743             : JS_PUBLIC_API(bool)
     744             : JS_StringHasBeenPinned(JSContext* cx, JSString* str);
     745             : 
     746             : namespace JS {
     747             : 
     748             : /**
     749             :  * Container class for passing in script source buffers to the JS engine.  This
     750             :  * not only groups the buffer and length values, it also provides a way to
     751             :  * optionally pass ownership of the buffer to the JS engine without copying.
     752             :  * Rules for use:
     753             :  *
     754             :  *  1) The data array must be allocated with js_malloc() or js_realloc() if
     755             :  *     ownership is being granted to the SourceBufferHolder.
     756             :  *  2) If ownership is not given to the SourceBufferHolder, then the memory
     757             :  *     must be kept alive until the JS compilation is complete.
     758             :  *  3) Any code calling SourceBufferHolder::take() must guarantee to keep the
     759             :  *     memory alive until JS compilation completes.  Normally only the JS
     760             :  *     engine should be calling take().
     761             :  *
     762             :  * Example use:
     763             :  *
     764             :  *    size_t length = 512;
     765             :  *    char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
     766             :  *    JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
     767             :  *    JS::Compile(cx, options, srcBuf);
     768             :  */
     769             : class MOZ_STACK_CLASS SourceBufferHolder final
     770             : {
     771             :   public:
     772             :     enum Ownership {
     773             :       NoOwnership,
     774             :       GiveOwnership
     775             :     };
     776             : 
     777         298 :     SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
     778         298 :       : data_(data),
     779             :         length_(dataLength),
     780         298 :         ownsChars_(ownership == GiveOwnership)
     781             :     {
     782             :         // Ensure that null buffers properly return an unowned, empty,
     783             :         // null-terminated string.
     784             :         static const char16_t NullChar_ = 0;
     785         298 :         if (!get()) {
     786           0 :             data_ = &NullChar_;
     787           0 :             length_ = 0;
     788           0 :             ownsChars_ = false;
     789             :         }
     790         298 :     }
     791             : 
     792             :     SourceBufferHolder(SourceBufferHolder&& other)
     793             :       : data_(other.data_),
     794             :         length_(other.length_),
     795             :         ownsChars_(other.ownsChars_)
     796             :     {
     797             :         other.data_ = nullptr;
     798             :         other.length_ = 0;
     799             :         other.ownsChars_ = false;
     800             :     }
     801             : 
     802         590 :     ~SourceBufferHolder() {
     803         295 :         if (ownsChars_)
     804          17 :             js_free(const_cast<char16_t*>(data_));
     805         295 :     }
     806             : 
     807             :     // Access the underlying source buffer without affecting ownership.
     808        1527 :     const char16_t* get() const { return data_; }
     809             : 
     810             :     // Length of the source buffer in char16_t code units (not bytes)
     811        1661 :     size_t length() const { return length_; }
     812             : 
     813             :     // Returns true if the SourceBufferHolder owns the buffer and will free
     814             :     // it upon destruction.  If true, it is legal to call take().
     815         126 :     bool ownsChars() const { return ownsChars_; }
     816             : 
     817             :     // Retrieve and take ownership of the underlying data buffer.  The caller
     818             :     // is now responsible for calling js_free() on the returned value, *but only
     819             :     // after JS script compilation has completed*.
     820             :     //
     821             :     // After the buffer has been taken the SourceBufferHolder functions as if
     822             :     // it had been constructed on an unowned buffer;  get() and length() still
     823             :     // work.  In order for this to be safe the taken buffer must be kept alive
     824             :     // until after JS script compilation completes as noted above.
     825             :     //
     826             :     // Note, it's the caller's responsibility to check ownsChars() before taking
     827             :     // the buffer.  Taking and then free'ing an unowned buffer will have dire
     828             :     // consequences.
     829          31 :     char16_t* take() {
     830          31 :         MOZ_ASSERT(ownsChars_);
     831          31 :         ownsChars_ = false;
     832          31 :         return const_cast<char16_t*>(data_);
     833             :     }
     834             : 
     835             :   private:
     836             :     SourceBufferHolder(SourceBufferHolder&) = delete;
     837             :     SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
     838             : 
     839             :     const char16_t* data_;
     840             :     size_t length_;
     841             :     bool ownsChars_;
     842             : };
     843             : 
     844             : struct TranscodeSource;
     845             : 
     846             : } /* namespace JS */
     847             : 
     848             : /************************************************************************/
     849             : 
     850             : /* Property attributes, set in JSPropertySpec and passed to API functions.
     851             :  *
     852             :  * NB: The data structure in which some of these values are stored only uses
     853             :  *     a uint8_t to store the relevant information. Proceed with caution if
     854             :  *     trying to reorder or change the the first byte worth of flags.
     855             :  */
     856             : 
     857             : /* property is visible to for/in loop */
     858             : static const uint8_t JSPROP_ENUMERATE =        0x01;
     859             : 
     860             : /* not settable: assignment is no-op.  This flag is only valid when neither
     861             :    JSPROP_GETTER nor JSPROP_SETTER is set. */
     862             : static const uint8_t JSPROP_READONLY =         0x02;
     863             : 
     864             : /* property cannot be deleted */
     865             : static const uint8_t JSPROP_PERMANENT =        0x04;
     866             : 
     867             : /* Passed to JS_Define(UC)Property* and JS_DefineElement if getters/setters are
     868             :    JSGetterOp/JSSetterOp */
     869             : static const uint8_t JSPROP_PROPOP_ACCESSORS = 0x08;
     870             : 
     871             : /* property holds getter function */
     872             : static const uint8_t JSPROP_GETTER =           0x10;
     873             : 
     874             : /* property holds setter function */
     875             : static const uint8_t JSPROP_SETTER =           0x20;
     876             : 
     877             : /* don't allocate a value slot for this property; don't copy the property on set
     878             :    of the same-named property in an object that delegates to a prototype
     879             :    containing this property */
     880             : static const uint8_t JSPROP_SHARED =           0x40;
     881             : 
     882             : /* internal JS engine use only */
     883             : static const uint8_t JSPROP_INTERNAL_USE_BIT = 0x80;
     884             : 
     885             : /* use JS_PropertyStub getter/setter instead of defaulting to class gsops for
     886             :    property holding function */
     887             : static const unsigned JSFUN_STUB_GSOPS =      0x200;
     888             : 
     889             : /* native that can be called as a ctor */
     890             : static const unsigned JSFUN_CONSTRUCTOR =     0x400;
     891             : 
     892             : /* | of all the JSFUN_* flags */
     893             : static const unsigned JSFUN_FLAGS_MASK =      0x600;
     894             : 
     895             : /*
     896             :  * If set, will allow redefining a non-configurable property, but only on a
     897             :  * non-DOM global.  This is a temporary hack that will need to go away in bug
     898             :  * 1105518.
     899             :  */
     900             : static const unsigned JSPROP_REDEFINE_NONCONFIGURABLE = 0x1000;
     901             : 
     902             : /*
     903             :  * Resolve hooks and enumerate hooks must pass this flag when calling
     904             :  * JS_Define* APIs to reify lazily-defined properties.
     905             :  *
     906             :  * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
     907             :  * engine to skip the resolve hook when performing the lookup at the beginning
     908             :  * of property definition. This keeps the resolve hook from accidentally
     909             :  * triggering itself: unchecked recursion.
     910             :  *
     911             :  * For enumerate hooks, triggering the resolve hook would be merely silly, not
     912             :  * fatal, except in some cases involving non-configurable properties.
     913             :  */
     914             : static const unsigned JSPROP_RESOLVING =         0x2000;
     915             : 
     916             : /* ignore the value in JSPROP_ENUMERATE.  This flag only valid when defining
     917             :    over an existing property. */
     918             : static const unsigned JSPROP_IGNORE_ENUMERATE =  0x4000;
     919             : 
     920             : /* ignore the value in JSPROP_READONLY.  This flag only valid when defining over
     921             :    an existing property. */
     922             : static const unsigned JSPROP_IGNORE_READONLY =   0x8000;
     923             : 
     924             : /* ignore the value in JSPROP_PERMANENT.  This flag only valid when defining
     925             :    over an existing property. */
     926             : static const unsigned JSPROP_IGNORE_PERMANENT = 0x10000;
     927             : 
     928             : /* ignore the Value in the descriptor. Nothing was specified when passed to
     929             :    Object.defineProperty from script. */
     930             : static const unsigned JSPROP_IGNORE_VALUE =     0x20000;
     931             : 
     932             : /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
     933             : extern JS_PUBLIC_API(int64_t)
     934             : JS_Now(void);
     935             : 
     936             : /** Don't want to export data, so provide accessors for non-inline Values. */
     937             : extern JS_PUBLIC_API(JS::Value)
     938             : JS_GetNaNValue(JSContext* cx);
     939             : 
     940             : extern JS_PUBLIC_API(JS::Value)
     941             : JS_GetNegativeInfinityValue(JSContext* cx);
     942             : 
     943             : extern JS_PUBLIC_API(JS::Value)
     944             : JS_GetPositiveInfinityValue(JSContext* cx);
     945             : 
     946             : extern JS_PUBLIC_API(JS::Value)
     947             : JS_GetEmptyStringValue(JSContext* cx);
     948             : 
     949             : extern JS_PUBLIC_API(JSString*)
     950             : JS_GetEmptyString(JSContext* cx);
     951             : 
     952             : extern JS_PUBLIC_API(bool)
     953             : JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp);
     954             : 
     955             : extern JS_PUBLIC_API(JSFunction*)
     956             : JS_ValueToFunction(JSContext* cx, JS::HandleValue v);
     957             : 
     958             : extern JS_PUBLIC_API(JSFunction*)
     959             : JS_ValueToConstructor(JSContext* cx, JS::HandleValue v);
     960             : 
     961             : extern JS_PUBLIC_API(JSString*)
     962             : JS_ValueToSource(JSContext* cx, JS::Handle<JS::Value> v);
     963             : 
     964             : extern JS_PUBLIC_API(bool)
     965             : JS_DoubleIsInt32(double d, int32_t* ip);
     966             : 
     967             : extern JS_PUBLIC_API(JSType)
     968             : JS_TypeOfValue(JSContext* cx, JS::Handle<JS::Value> v);
     969             : 
     970             : namespace JS {
     971             : 
     972             : extern JS_PUBLIC_API(const char*)
     973             : InformalValueTypeName(const JS::Value& v);
     974             : 
     975             : } /* namespace JS */
     976             : 
     977             : extern JS_PUBLIC_API(bool)
     978             : JS_StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
     979             : 
     980             : extern JS_PUBLIC_API(bool)
     981             : JS_LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
     982             : 
     983             : extern JS_PUBLIC_API(bool)
     984             : JS_SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
     985             : 
     986             : /** True iff fun is the global eval function. */
     987             : extern JS_PUBLIC_API(bool)
     988             : JS_IsBuiltinEvalFunction(JSFunction* fun);
     989             : 
     990             : /** True iff fun is the Function constructor. */
     991             : extern JS_PUBLIC_API(bool)
     992             : JS_IsBuiltinFunctionConstructor(JSFunction* fun);
     993             : 
     994             : /************************************************************************/
     995             : 
     996             : /*
     997             :  * Locking, contexts, and memory allocation.
     998             :  *
     999             :  * It is important that SpiderMonkey be initialized, and the first context
    1000             :  * be created, in a single-threaded fashion.  Otherwise the behavior of the
    1001             :  * library is undefined.
    1002             :  * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
    1003             :  */
    1004             : 
    1005             : // Create a new runtime, with a single cooperative context for this thread.
    1006             : // On success, the new context will be the active context for the runtime.
    1007             : extern JS_PUBLIC_API(JSContext*)
    1008             : JS_NewContext(uint32_t maxbytes,
    1009             :               uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
    1010             :               JSRuntime* parentRuntime = nullptr);
    1011             : 
    1012             : // The methods below for controlling the active context in a cooperatively
    1013             : // multithreaded runtime are not threadsafe, and the caller must ensure they
    1014             : // are called serially if there is a chance for contention between threads.
    1015             : 
    1016             : // Called from the active context for a runtime, yield execution so that
    1017             : // this context is no longer active and can no longer use the API.
    1018             : extern JS_PUBLIC_API(void)
    1019             : JS_YieldCooperativeContext(JSContext* cx);
    1020             : 
    1021             : // Called from a context whose runtime has no active context, this thread
    1022             : // becomes the active context for that runtime and may use the API.
    1023             : extern JS_PUBLIC_API(void)
    1024             : JS_ResumeCooperativeContext(JSContext* cx);
    1025             : 
    1026             : // Create a new context on this thread for cooperative multithreading in the
    1027             : // same runtime as siblingContext. Called on a runtime (as indicated by
    1028             : // siblingContet) which has no active context, on success the new context will
    1029             : // become the runtime's active context.
    1030             : extern JS_PUBLIC_API(JSContext*)
    1031             : JS_NewCooperativeContext(JSContext* siblingContext);
    1032             : 
    1033             : // Destroy a context allocated with JS_NewContext or JS_NewCooperativeContext.
    1034             : // The context must be the current active context in the runtime, and after
    1035             : // this call the runtime will have no active context.
    1036             : extern JS_PUBLIC_API(void)
    1037             : JS_DestroyContext(JSContext* cx);
    1038             : 
    1039             : JS_PUBLIC_API(void*)
    1040             : JS_GetContextPrivate(JSContext* cx);
    1041             : 
    1042             : JS_PUBLIC_API(void)
    1043             : JS_SetContextPrivate(JSContext* cx, void* data);
    1044             : 
    1045             : extern JS_PUBLIC_API(JSRuntime*)
    1046             : JS_GetParentRuntime(JSContext* cx);
    1047             : 
    1048             : extern JS_PUBLIC_API(JSRuntime*)
    1049             : JS_GetRuntime(JSContext* cx);
    1050             : 
    1051             : extern JS_PUBLIC_API(void)
    1052             : JS_BeginRequest(JSContext* cx);
    1053             : 
    1054             : extern JS_PUBLIC_API(void)
    1055             : JS_EndRequest(JSContext* cx);
    1056             : 
    1057             : extern JS_PUBLIC_API(void)
    1058             : JS_SetFutexCanWait(JSContext* cx);
    1059             : 
    1060             : namespace JS {
    1061             : 
    1062             : // Single threaded execution callbacks are used to notify API clients that a
    1063             : // feature is in use on a context's runtime that is not yet compatible with
    1064             : // cooperatively multithreaded execution.
    1065             : //
    1066             : // Between a call to BeginSingleThreadedExecutionCallback and a corresponding
    1067             : // call to EndSingleThreadedExecutionCallback, only one thread at a time may
    1068             : // enter compartments in the runtime. The begin callback may yield as necessary
    1069             : // to permit other threads to finish up what they're doing, while the end
    1070             : // callback may not yield or otherwise operate on the runtime (it may be called
    1071             : // during GC).
    1072             : //
    1073             : // These callbacks may be left unspecified for runtimes which only ever have a
    1074             : // single context.
    1075             : typedef void (*BeginSingleThreadedExecutionCallback)(JSContext* cx);
    1076             : typedef void (*EndSingleThreadedExecutionCallback)(JSContext* cx);
    1077             : 
    1078             : extern JS_PUBLIC_API(void)
    1079             : SetSingleThreadedExecutionCallbacks(JSContext* cx,
    1080             :                                     BeginSingleThreadedExecutionCallback begin,
    1081             :                                     EndSingleThreadedExecutionCallback end);
    1082             : 
    1083             : } // namespace JS
    1084             : 
    1085             : namespace js {
    1086             : 
    1087             : void
    1088             : AssertHeapIsIdle();
    1089             : 
    1090             : } /* namespace js */
    1091             : 
    1092             : class MOZ_RAII JSAutoRequest
    1093             : {
    1094             :   public:
    1095       55782 :     explicit JSAutoRequest(JSContext* cx
    1096             :                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    1097       55782 :       : mContext(cx)
    1098             :     {
    1099       55782 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    1100       55782 :         JS_BeginRequest(mContext);
    1101       55782 :     }
    1102      111564 :     ~JSAutoRequest() {
    1103       55782 :         JS_EndRequest(mContext);
    1104       55782 :     }
    1105             : 
    1106             :   protected:
    1107             :     JSContext* mContext;
    1108             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1109             : 
    1110             : #if 0
    1111             :   private:
    1112             :     static void* operator new(size_t) CPP_THROW_NEW { return 0; }
    1113             :     static void operator delete(void*, size_t) { }
    1114             : #endif
    1115             : };
    1116             : 
    1117             : extern JS_PUBLIC_API(JSVersion)
    1118             : JS_GetVersion(JSContext* cx);
    1119             : 
    1120             : /**
    1121             :  * Mutate the version on the compartment. This is generally discouraged, but
    1122             :  * necessary to support the version mutation in the js and xpc shell command
    1123             :  * set.
    1124             :  *
    1125             :  * It would be nice to put this in jsfriendapi, but the linkage requirements
    1126             :  * of the shells make that impossible.
    1127             :  */
    1128             : JS_PUBLIC_API(void)
    1129             : JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version);
    1130             : 
    1131             : extern JS_PUBLIC_API(const char*)
    1132             : JS_VersionToString(JSVersion version);
    1133             : 
    1134             : extern JS_PUBLIC_API(JSVersion)
    1135             : JS_StringToVersion(const char* string);
    1136             : 
    1137             : namespace JS {
    1138             : 
    1139             : class JS_PUBLIC_API(ContextOptions) {
    1140             :   public:
    1141          47 :     ContextOptions()
    1142          47 :       : baseline_(true),
    1143             :         ion_(true),
    1144             :         asmJS_(true),
    1145             :         wasm_(false),
    1146             :         wasmAlwaysBaseline_(false),
    1147             :         throwOnAsmJSValidationFailure_(false),
    1148             :         nativeRegExp_(true),
    1149             :         unboxedArrays_(false),
    1150             :         asyncStack_(true),
    1151             :         throwOnDebuggeeWouldRun_(true),
    1152             :         dumpStackOnDebuggeeWouldRun_(false),
    1153             :         werror_(false),
    1154             :         strictMode_(false),
    1155             :         extraWarnings_(false),
    1156             : #ifdef NIGHTLY_BUILD
    1157          47 :         forEachStatement_(false)
    1158             : #else
    1159             :         forEachStatement_(true)
    1160             : #endif
    1161             :     {
    1162          47 :     }
    1163             : 
    1164      133328 :     bool baseline() const { return baseline_; }
    1165           4 :     ContextOptions& setBaseline(bool flag) {
    1166           4 :         baseline_ = flag;
    1167           4 :         return *this;
    1168             :     }
    1169             :     ContextOptions& toggleBaseline() {
    1170             :         baseline_ = !baseline_;
    1171             :         return *this;
    1172             :     }
    1173             : 
    1174       62196 :     bool ion() const { return ion_; }
    1175           4 :     ContextOptions& setIon(bool flag) {
    1176           4 :         ion_ = flag;
    1177           4 :         return *this;
    1178             :     }
    1179           0 :     ContextOptions& toggleIon() {
    1180           0 :         ion_ = !ion_;
    1181           0 :         return *this;
    1182             :     }
    1183             : 
    1184       21274 :     bool asmJS() const { return asmJS_; }
    1185           4 :     ContextOptions& setAsmJS(bool flag) {
    1186           4 :         asmJS_ = flag;
    1187           4 :         return *this;
    1188             :     }
    1189           0 :     ContextOptions& toggleAsmJS() {
    1190           0 :         asmJS_ = !asmJS_;
    1191           0 :         return *this;
    1192             :     }
    1193             : 
    1194          12 :     bool wasm() const { return wasm_; }
    1195           4 :     ContextOptions& setWasm(bool flag) {
    1196           4 :         wasm_ = flag;
    1197           4 :         return *this;
    1198             :     }
    1199           0 :     ContextOptions& toggleWasm() {
    1200           0 :         wasm_ = !wasm_;
    1201           0 :         return *this;
    1202             :     }
    1203             : 
    1204           0 :     bool wasmAlwaysBaseline() const { return wasmAlwaysBaseline_; }
    1205           4 :     ContextOptions& setWasmAlwaysBaseline(bool flag) {
    1206           4 :         wasmAlwaysBaseline_ = flag;
    1207           4 :         return *this;
    1208             :     }
    1209             :     ContextOptions& toggleWasmAlwaysBaseline() {
    1210             :         wasmAlwaysBaseline_ = !wasmAlwaysBaseline_;
    1211             :         return *this;
    1212             :     }
    1213             : 
    1214       21274 :     bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; }
    1215           4 :     ContextOptions& setThrowOnAsmJSValidationFailure(bool flag) {
    1216           4 :         throwOnAsmJSValidationFailure_ = flag;
    1217           4 :         return *this;
    1218             :     }
    1219             :     ContextOptions& toggleThrowOnAsmJSValidationFailure() {
    1220             :         throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
    1221             :         return *this;
    1222             :     }
    1223             : 
    1224          40 :     bool nativeRegExp() const { return nativeRegExp_; }
    1225           4 :     ContextOptions& setNativeRegExp(bool flag) {
    1226           4 :         nativeRegExp_ = flag;
    1227           4 :         return *this;
    1228             :     }
    1229             : 
    1230         711 :     bool unboxedArrays() const { return unboxedArrays_; }
    1231             :     ContextOptions& setUnboxedArrays(bool flag) {
    1232             :         unboxedArrays_ = flag;
    1233             :         return *this;
    1234             :     }
    1235             : 
    1236        1225 :     bool asyncStack() const { return asyncStack_; }
    1237           4 :     ContextOptions& setAsyncStack(bool flag) {
    1238           4 :         asyncStack_ = flag;
    1239           4 :         return *this;
    1240             :     }
    1241             : 
    1242           0 :     bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; }
    1243           3 :     ContextOptions& setThrowOnDebuggeeWouldRun(bool flag) {
    1244           3 :         throwOnDebuggeeWouldRun_ = flag;
    1245           3 :         return *this;
    1246             :     }
    1247             : 
    1248           0 :     bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; }
    1249           3 :     ContextOptions& setDumpStackOnDebuggeeWouldRun(bool flag) {
    1250           3 :         dumpStackOnDebuggeeWouldRun_ = flag;
    1251           3 :         return *this;
    1252             :     }
    1253             : 
    1254       21519 :     bool werror() const { return werror_; }
    1255           4 :     ContextOptions& setWerror(bool flag) {
    1256           4 :         werror_ = flag;
    1257           4 :         return *this;
    1258             :     }
    1259           0 :     ContextOptions& toggleWerror() {
    1260           0 :         werror_ = !werror_;
    1261           0 :         return *this;
    1262             :     }
    1263             : 
    1264       21519 :     bool strictMode() const { return strictMode_; }
    1265           0 :     ContextOptions& setStrictMode(bool flag) {
    1266           0 :         strictMode_ = flag;
    1267           0 :         return *this;
    1268             :     }
    1269           0 :     ContextOptions& toggleStrictMode() {
    1270           0 :         strictMode_ = !strictMode_;
    1271           0 :         return *this;
    1272             :     }
    1273             : 
    1274       25468 :     bool extraWarnings() const { return extraWarnings_; }
    1275           4 :     ContextOptions& setExtraWarnings(bool flag) {
    1276           4 :         extraWarnings_ = flag;
    1277           4 :         return *this;
    1278             :     }
    1279           0 :     ContextOptions& toggleExtraWarnings() {
    1280           0 :         extraWarnings_ = !extraWarnings_;
    1281           0 :         return *this;
    1282             :     }
    1283             : 
    1284       21274 :     bool forEachStatement() const { return forEachStatement_; }
    1285           0 :     ContextOptions& setForEachStatement(bool flag) {
    1286           0 :         forEachStatement_ = flag;
    1287           0 :         return *this;
    1288             :     }
    1289             : 
    1290             : #ifdef FUZZING
    1291             :     bool fuzzing() const { return fuzzing_; }
    1292             :     ContextOptions& setFuzzing(bool flag) {
    1293             :         fuzzing_ = flag;
    1294             :         return *this;
    1295             :     }
    1296             : #endif
    1297             : 
    1298             :   private:
    1299             :     bool baseline_ : 1;
    1300             :     bool ion_ : 1;
    1301             :     bool asmJS_ : 1;
    1302             :     bool wasm_ : 1;
    1303             :     bool wasmAlwaysBaseline_ : 1;
    1304             :     bool throwOnAsmJSValidationFailure_ : 1;
    1305             :     bool nativeRegExp_ : 1;
    1306             :     bool unboxedArrays_ : 1;
    1307             :     bool asyncStack_ : 1;
    1308             :     bool throwOnDebuggeeWouldRun_ : 1;
    1309             :     bool dumpStackOnDebuggeeWouldRun_ : 1;
    1310             :     bool werror_ : 1;
    1311             :     bool strictMode_ : 1;
    1312             :     bool extraWarnings_ : 1;
    1313             :     bool forEachStatement_: 1;
    1314             : #ifdef FUZZING
    1315             :     bool fuzzing_ : 1;
    1316             : #endif
    1317             : 
    1318             : };
    1319             : 
    1320             : JS_PUBLIC_API(ContextOptions&)
    1321             : ContextOptionsRef(JSContext* cx);
    1322             : 
    1323             : /**
    1324             :  * Initialize the runtime's self-hosted code. Embeddings should call this
    1325             :  * exactly once per runtime/context, before the first JS_NewGlobalObject
    1326             :  * call.
    1327             :  */
    1328             : JS_PUBLIC_API(bool)
    1329             : InitSelfHostedCode(JSContext* cx);
    1330             : 
    1331             : /**
    1332             :  * Asserts (in debug and release builds) that `obj` belongs to the current
    1333             :  * thread's context.
    1334             :  */
    1335             : JS_PUBLIC_API(void)
    1336             : AssertObjectBelongsToCurrentThread(JSObject* obj);
    1337             : 
    1338             : } /* namespace JS */
    1339             : 
    1340             : extern JS_PUBLIC_API(const char*)
    1341             : JS_GetImplementationVersion(void);
    1342             : 
    1343             : extern JS_PUBLIC_API(void)
    1344             : JS_SetDestroyCompartmentCallback(JSContext* cx, JSDestroyCompartmentCallback callback);
    1345             : 
    1346             : extern JS_PUBLIC_API(void)
    1347             : JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx,
    1348             :                                              JSSizeOfIncludingThisCompartmentCallback callback);
    1349             : 
    1350             : extern JS_PUBLIC_API(void)
    1351             : JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback);
    1352             : 
    1353             : extern JS_PUBLIC_API(void)
    1354             : JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks);
    1355             : 
    1356             : extern JS_PUBLIC_API(void)
    1357             : JS_SetExternalStringSizeofCallback(JSContext* cx, JSExternalStringSizeofCallback callback);
    1358             : 
    1359             : extern JS_PUBLIC_API(void)
    1360             : JS_SetCompartmentPrivate(JSCompartment* compartment, void* data);
    1361             : 
    1362             : extern JS_PUBLIC_API(void*)
    1363             : JS_GetCompartmentPrivate(JSCompartment* compartment);
    1364             : 
    1365             : extern JS_PUBLIC_API(void)
    1366             : JS_SetZoneUserData(JS::Zone* zone, void* data);
    1367             : 
    1368             : extern JS_PUBLIC_API(void*)
    1369             : JS_GetZoneUserData(JS::Zone* zone);
    1370             : 
    1371             : extern JS_PUBLIC_API(bool)
    1372             : JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp);
    1373             : 
    1374             : extern JS_PUBLIC_API(bool)
    1375             : JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp);
    1376             : 
    1377             : extern JS_PUBLIC_API(JSObject*)
    1378             : JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
    1379             : 
    1380             : extern JS_PUBLIC_API(bool)
    1381             : JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
    1382             : 
    1383             : /*
    1384             :  * At any time, a JSContext has a current (possibly-nullptr) compartment.
    1385             :  * Compartments are described in:
    1386             :  *
    1387             :  *   developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
    1388             :  *
    1389             :  * The current compartment of a context may be changed. The preferred way to do
    1390             :  * this is with JSAutoCompartment:
    1391             :  *
    1392             :  *   void foo(JSContext* cx, JSObject* obj) {
    1393             :  *     // in some compartment 'c'
    1394             :  *     {
    1395             :  *       JSAutoCompartment ac(cx, obj);  // constructor enters
    1396             :  *       // in the compartment of 'obj'
    1397             :  *     }                                 // destructor leaves
    1398             :  *     // back in compartment 'c'
    1399             :  *   }
    1400             :  *
    1401             :  * For more complicated uses that don't neatly fit in a C++ stack frame, the
    1402             :  * compartment can entered and left using separate function calls:
    1403             :  *
    1404             :  *   void foo(JSContext* cx, JSObject* obj) {
    1405             :  *     // in 'oldCompartment'
    1406             :  *     JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj);
    1407             :  *     // in the compartment of 'obj'
    1408             :  *     JS_LeaveCompartment(cx, oldCompartment);
    1409             :  *     // back in 'oldCompartment'
    1410             :  *   }
    1411             :  *
    1412             :  * Note: these calls must still execute in a LIFO manner w.r.t all other
    1413             :  * enter/leave calls on the context. Furthermore, only the return value of a
    1414             :  * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
    1415             :  * the corresponding JS_LeaveCompartment call.
    1416             :  */
    1417             : 
    1418             : class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment)
    1419             : {
    1420             :     JSContext* cx_;
    1421             :     JSCompartment* oldCompartment_;
    1422             :   public:
    1423             :     JSAutoCompartment(JSContext* cx, JSObject* target
    1424             :                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
    1425             :     JSAutoCompartment(JSContext* cx, JSScript* target
    1426             :                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
    1427             :     ~JSAutoCompartment();
    1428             : 
    1429             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1430             : };
    1431             : 
    1432             : class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment)
    1433             : {
    1434             :     JSContext* cx_;
    1435             :     JSCompartment* oldCompartment_;
    1436             :   public:
    1437             :     explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull
    1438             :                                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
    1439             :     ~JSAutoNullableCompartment();
    1440             : 
    1441             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    1442             : };
    1443             : 
    1444             : /** NB: This API is infallible; a nullptr return value does not indicate error. */
    1445             : extern JS_PUBLIC_API(JSCompartment*)
    1446             : JS_EnterCompartment(JSContext* cx, JSObject* target);
    1447             : 
    1448             : extern JS_PUBLIC_API(void)
    1449             : JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment);
    1450             : 
    1451             : typedef void (*JSIterateCompartmentCallback)(JSContext* cx, void* data, JSCompartment* compartment);
    1452             : 
    1453             : /**
    1454             :  * This function calls |compartmentCallback| on every compartment. Beware that
    1455             :  * there is no guarantee that the compartment will survive after the callback
    1456             :  * returns. Also, barriers are disabled via the TraceSession.
    1457             :  */
    1458             : extern JS_PUBLIC_API(void)
    1459             : JS_IterateCompartments(JSContext* cx, void* data,
    1460             :                        JSIterateCompartmentCallback compartmentCallback);
    1461             : 
    1462             : /**
    1463             :  * Mark a jsid after entering a new compartment. Different zones separately
    1464             :  * mark the ids in a runtime, and this must be used any time an id is obtained
    1465             :  * from one compartment and then used in another compartment, unless the two
    1466             :  * compartments are guaranteed to be in the same zone.
    1467             :  */
    1468             : extern JS_PUBLIC_API(void)
    1469             : JS_MarkCrossZoneId(JSContext* cx, jsid id);
    1470             : 
    1471             : /**
    1472             :  * If value stores a jsid (an atomized string or symbol), mark that id as for
    1473             :  * JS_MarkCrossZoneId.
    1474             :  */
    1475             : extern JS_PUBLIC_API(void)
    1476             : JS_MarkCrossZoneIdValue(JSContext* cx, const JS::Value& value);
    1477             : 
    1478             : /**
    1479             :  * Initialize standard JS class constructors, prototypes, and any top-level
    1480             :  * functions and constants associated with the standard classes (e.g. isNaN
    1481             :  * for Number).
    1482             :  *
    1483             :  * NB: This sets cx's global object to obj if it was null.
    1484             :  */
    1485             : extern JS_PUBLIC_API(bool)
    1486             : JS_InitStandardClasses(JSContext* cx, JS::Handle<JSObject*> obj);
    1487             : 
    1488             : /**
    1489             :  * Resolve id, which must contain either a string or an int, to a standard
    1490             :  * class name in obj if possible, defining the class's constructor and/or
    1491             :  * prototype and storing true in *resolved.  If id does not name a standard
    1492             :  * class or a top-level property induced by initializing a standard class,
    1493             :  * store false in *resolved and just return true.  Return false on error,
    1494             :  * as usual for bool result-typed API entry points.
    1495             :  *
    1496             :  * This API can be called directly from a global object class's resolve op,
    1497             :  * to define standard classes lazily. The class should either have an enumerate
    1498             :  * hook that calls JS_EnumerateStandardClasses, or a newEnumerate hook that
    1499             :  * calls JS_NewEnumerateStandardClasses. newEnumerate is preferred because it's
    1500             :  * faster (does not define all standard classes).
    1501             :  */
    1502             : extern JS_PUBLIC_API(bool)
    1503             : JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved);
    1504             : 
    1505             : extern JS_PUBLIC_API(bool)
    1506             : JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj);
    1507             : 
    1508             : extern JS_PUBLIC_API(bool)
    1509             : JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj);
    1510             : 
    1511             : extern JS_PUBLIC_API(bool)
    1512             : JS_NewEnumerateStandardClasses(JSContext* cx, JS::HandleObject obj, JS::AutoIdVector& properties,
    1513             :                                bool enumerableOnly);
    1514             : 
    1515             : extern JS_PUBLIC_API(bool)
    1516             : JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
    1517             : 
    1518             : extern JS_PUBLIC_API(bool)
    1519             : JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
    1520             : 
    1521             : namespace JS {
    1522             : 
    1523             : /*
    1524             :  * Determine if the given object is an instance/prototype/constructor for a standard
    1525             :  * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
    1526             :  */
    1527             : 
    1528             : extern JS_PUBLIC_API(JSProtoKey)
    1529             : IdentifyStandardInstance(JSObject* obj);
    1530             : 
    1531             : extern JS_PUBLIC_API(JSProtoKey)
    1532             : IdentifyStandardPrototype(JSObject* obj);
    1533             : 
    1534             : extern JS_PUBLIC_API(JSProtoKey)
    1535             : IdentifyStandardInstanceOrPrototype(JSObject* obj);
    1536             : 
    1537             : extern JS_PUBLIC_API(JSProtoKey)
    1538             : IdentifyStandardConstructor(JSObject* obj);
    1539             : 
    1540             : extern JS_PUBLIC_API(void)
    1541             : ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp);
    1542             : 
    1543             : } /* namespace JS */
    1544             : 
    1545             : extern JS_PUBLIC_API(JSProtoKey)
    1546             : JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
    1547             : 
    1548             : /**
    1549             :  * Returns the original value of |Function.prototype| from the global object in
    1550             :  * which |forObj| was created.
    1551             :  */
    1552             : extern JS_PUBLIC_API(JSObject*)
    1553             : JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj);
    1554             : 
    1555             : /**
    1556             :  * Returns the original value of |Object.prototype| from the global object in
    1557             :  * which |forObj| was created.
    1558             :  */
    1559             : extern JS_PUBLIC_API(JSObject*)
    1560             : JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj);
    1561             : 
    1562             : /**
    1563             :  * Returns the original value of |Array.prototype| from the global object in
    1564             :  * which |forObj| was created.
    1565             :  */
    1566             : extern JS_PUBLIC_API(JSObject*)
    1567             : JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj);
    1568             : 
    1569             : /**
    1570             :  * Returns the original value of |Error.prototype| from the global
    1571             :  * object of the current compartment of cx.
    1572             :  */
    1573             : extern JS_PUBLIC_API(JSObject*)
    1574             : JS_GetErrorPrototype(JSContext* cx);
    1575             : 
    1576             : /**
    1577             :  * Returns the %IteratorPrototype% object that all built-in iterator prototype
    1578             :  * chains go through for the global object of the current compartment of cx.
    1579             :  */
    1580             : extern JS_PUBLIC_API(JSObject*)
    1581             : JS_GetIteratorPrototype(JSContext* cx);
    1582             : 
    1583             : extern JS_PUBLIC_API(JSObject*)
    1584             : JS_GetGlobalForObject(JSContext* cx, JSObject* obj);
    1585             : 
    1586             : extern JS_PUBLIC_API(bool)
    1587             : JS_IsGlobalObject(JSObject* obj);
    1588             : 
    1589             : extern JS_PUBLIC_API(JSObject*)
    1590             : JS_GlobalLexicalEnvironment(JSObject* obj);
    1591             : 
    1592             : extern JS_PUBLIC_API(bool)
    1593             : JS_HasExtensibleLexicalEnvironment(JSObject* obj);
    1594             : 
    1595             : extern JS_PUBLIC_API(JSObject*)
    1596             : JS_ExtensibleLexicalEnvironment(JSObject* obj);
    1597             : 
    1598             : /**
    1599             :  * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
    1600             :  * or if |c|'s global has been collected.
    1601             :  */
    1602             : extern JS_PUBLIC_API(JSObject*)
    1603             : JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c);
    1604             : 
    1605             : namespace JS {
    1606             : 
    1607             : extern JS_PUBLIC_API(JSObject*)
    1608             : CurrentGlobalOrNull(JSContext* cx);
    1609             : 
    1610             : } // namespace JS
    1611             : 
    1612             : /**
    1613             :  * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
    1614             :  * given global.
    1615             :  */
    1616             : extern JS_PUBLIC_API(bool)
    1617             : JS_InitReflectParse(JSContext* cx, JS::HandleObject global);
    1618             : 
    1619             : /**
    1620             :  * Add various profiling-related functions as properties of the given object.
    1621             :  * Defined in builtin/Profilers.cpp.
    1622             :  */
    1623             : extern JS_PUBLIC_API(bool)
    1624             : JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj);
    1625             : 
    1626             : /* Defined in vm/Debugger.cpp. */
    1627             : extern JS_PUBLIC_API(bool)
    1628             : JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj);
    1629             : 
    1630             : #ifdef JS_HAS_CTYPES
    1631             : /**
    1632             :  * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
    1633             :  * object will be sealed.
    1634             :  */
    1635             : extern JS_PUBLIC_API(bool)
    1636             : JS_InitCTypesClass(JSContext* cx, JS::HandleObject global);
    1637             : 
    1638             : /**
    1639             :  * Convert a unicode string 'source' of length 'slen' to the platform native
    1640             :  * charset, returning a null-terminated string allocated with JS_malloc. On
    1641             :  * failure, this function should report an error.
    1642             :  */
    1643             : typedef char*
    1644             : (* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen);
    1645             : 
    1646             : /**
    1647             :  * Set of function pointers that ctypes can use for various internal functions.
    1648             :  * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
    1649             :  * and will result in the applicable ctypes functionality not being available.
    1650             :  */
    1651             : struct JSCTypesCallbacks {
    1652             :     JSCTypesUnicodeToNativeFun unicodeToNative;
    1653             : };
    1654             : 
    1655             : /**
    1656             :  * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
    1657             :  * pointer to static data that exists for the lifetime of 'ctypesObj', but it
    1658             :  * may safely be altered after calling this function and without having
    1659             :  * to call this function again.
    1660             :  */
    1661             : extern JS_PUBLIC_API(void)
    1662             : JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks);
    1663             : #endif
    1664             : 
    1665             : extern JS_PUBLIC_API(void*)
    1666             : JS_malloc(JSContext* cx, size_t nbytes);
    1667             : 
    1668             : extern JS_PUBLIC_API(void*)
    1669             : JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes);
    1670             : 
    1671             : /**
    1672             :  * A wrapper for js_free(p) that may delay js_free(p) invocation as a
    1673             :  * performance optimization.
    1674             :  * cx may be nullptr.
    1675             :  */
    1676             : extern JS_PUBLIC_API(void)
    1677             : JS_free(JSContext* cx, void* p);
    1678             : 
    1679             : /**
    1680             :  * A wrapper for js_free(p) that may delay js_free(p) invocation as a
    1681             :  * performance optimization as specified by the given JSFreeOp instance.
    1682             :  */
    1683             : extern JS_PUBLIC_API(void)
    1684             : JS_freeop(JSFreeOp* fop, void* p);
    1685             : 
    1686             : extern JS_PUBLIC_API(void)
    1687             : JS_updateMallocCounter(JSContext* cx, size_t nbytes);
    1688             : 
    1689             : extern JS_PUBLIC_API(char*)
    1690             : JS_strdup(JSContext* cx, const char* s);
    1691             : 
    1692             : /**
    1693             :  * Register externally maintained GC roots.
    1694             :  *
    1695             :  * traceOp: the trace operation. For each root the implementation should call
    1696             :  *          JS::TraceEdge whenever the root contains a traceable thing.
    1697             :  * data:    the data argument to pass to each invocation of traceOp.
    1698             :  */
    1699             : extern JS_PUBLIC_API(bool)
    1700             : JS_AddExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
    1701             : 
    1702             : /** Undo a call to JS_AddExtraGCRootsTracer. */
    1703             : extern JS_PUBLIC_API(void)
    1704             : JS_RemoveExtraGCRootsTracer(JSContext* cx, JSTraceDataOp traceOp, void* data);
    1705             : 
    1706             : /*
    1707             :  * Garbage collector API.
    1708             :  */
    1709             : extern JS_PUBLIC_API(void)
    1710             : JS_GC(JSContext* cx);
    1711             : 
    1712             : extern JS_PUBLIC_API(void)
    1713             : JS_MaybeGC(JSContext* cx);
    1714             : 
    1715             : extern JS_PUBLIC_API(void)
    1716             : JS_SetGCCallback(JSContext* cx, JSGCCallback cb, void* data);
    1717             : 
    1718             : extern JS_PUBLIC_API(void)
    1719             : JS_SetObjectsTenuredCallback(JSContext* cx, JSObjectsTenuredCallback cb,
    1720             :                              void* data);
    1721             : 
    1722             : extern JS_PUBLIC_API(bool)
    1723             : JS_AddFinalizeCallback(JSContext* cx, JSFinalizeCallback cb, void* data);
    1724             : 
    1725             : extern JS_PUBLIC_API(void)
    1726             : JS_RemoveFinalizeCallback(JSContext* cx, JSFinalizeCallback cb);
    1727             : 
    1728             : /*
    1729             :  * Weak pointers and garbage collection
    1730             :  *
    1731             :  * Weak pointers are by their nature not marked as part of garbage collection,
    1732             :  * but they may need to be updated in two cases after a GC:
    1733             :  *
    1734             :  *  1) Their referent was found not to be live and is about to be finalized
    1735             :  *  2) Their referent has been moved by a compacting GC
    1736             :  *
    1737             :  * To handle this, any part of the system that maintain weak pointers to
    1738             :  * JavaScript GC things must register a callback with
    1739             :  * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
    1740             :  * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
    1741             :  * about.
    1742             :  *
    1743             :  * Since sweeping is incremental, we have several callbacks to avoid repeatedly
    1744             :  * having to visit all embedder structures. The WeakPointerZonesCallback is
    1745             :  * called once for each strongly connected group of zones, whereas the
    1746             :  * WeakPointerCompartmentCallback is called once for each compartment that is
    1747             :  * visited while sweeping. Structures that cannot contain references in more
    1748             :  * than one compartment should sweep the relevant per-compartment structures
    1749             :  * using the latter callback to minimizer per-slice overhead.
    1750             :  *
    1751             :  * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
    1752             :  * referent is about to be finalized the pointer will be set to null. If the
    1753             :  * referent has been moved then the pointer will be updated to point to the new
    1754             :  * location.
    1755             :  *
    1756             :  * Callers of this method are responsible for updating any state that is
    1757             :  * dependent on the object's address. For example, if the object's address is
    1758             :  * used as a key in a hashtable, then the object must be removed and
    1759             :  * re-inserted with the correct hash.
    1760             :  */
    1761             : 
    1762             : extern JS_PUBLIC_API(bool)
    1763             : JS_AddWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb, void* data);
    1764             : 
    1765             : extern JS_PUBLIC_API(void)
    1766             : JS_RemoveWeakPointerZonesCallback(JSContext* cx, JSWeakPointerZonesCallback cb);
    1767             : 
    1768             : extern JS_PUBLIC_API(bool)
    1769             : JS_AddWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb,
    1770             :                                      void* data);
    1771             : 
    1772             : extern JS_PUBLIC_API(void)
    1773             : JS_RemoveWeakPointerCompartmentCallback(JSContext* cx, JSWeakPointerCompartmentCallback cb);
    1774             : 
    1775             : extern JS_PUBLIC_API(void)
    1776             : JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
    1777             : 
    1778             : extern JS_PUBLIC_API(void)
    1779             : JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
    1780             : 
    1781             : typedef enum JSGCParamKey {
    1782             :     /** Maximum nominal heap before last ditch GC. */
    1783             :     JSGC_MAX_BYTES          = 0,
    1784             : 
    1785             :     /** Number of JS_malloc bytes before last ditch GC. */
    1786             :     JSGC_MAX_MALLOC_BYTES   = 1,
    1787             : 
    1788             :     /** Maximum size of the generational GC nurseries. */
    1789             :     JSGC_MAX_NURSERY_BYTES  = 2,
    1790             : 
    1791             :     /** Amount of bytes allocated by the GC. */
    1792             :     JSGC_BYTES = 3,
    1793             : 
    1794             :     /** Number of times GC has been invoked. Includes both major and minor GC. */
    1795             :     JSGC_NUMBER = 4,
    1796             : 
    1797             :     /** Select GC mode. */
    1798             :     JSGC_MODE = 6,
    1799             : 
    1800             :     /** Number of cached empty GC chunks. */
    1801             :     JSGC_UNUSED_CHUNKS = 7,
    1802             : 
    1803             :     /** Total number of allocated GC chunks. */
    1804             :     JSGC_TOTAL_CHUNKS = 8,
    1805             : 
    1806             :     /** Max milliseconds to spend in an incremental GC slice. */
    1807             :     JSGC_SLICE_TIME_BUDGET = 9,
    1808             : 
    1809             :     /** Maximum size the GC mark stack can grow to. */
    1810             :     JSGC_MARK_STACK_LIMIT = 10,
    1811             : 
    1812             :     /**
    1813             :      * GCs less than this far apart in time will be considered 'high-frequency GCs'.
    1814             :      * See setGCLastBytes in jsgc.cpp.
    1815             :      */
    1816             :     JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
    1817             : 
    1818             :     /** Start of dynamic heap growth. */
    1819             :     JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
    1820             : 
    1821             :     /** End of dynamic heap growth. */
    1822             :     JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
    1823             : 
    1824             :     /** Upper bound of heap growth. */
    1825             :     JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
    1826             : 
    1827             :     /** Lower bound of heap growth. */
    1828             :     JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
    1829             : 
    1830             :     /** Heap growth for low frequency GCs. */
    1831             :     JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
    1832             : 
    1833             :     /**
    1834             :      * If false, the heap growth factor is fixed at 3. If true, it is determined
    1835             :      * based on whether GCs are high- or low- frequency.
    1836             :      */
    1837             :     JSGC_DYNAMIC_HEAP_GROWTH = 17,
    1838             : 
    1839             :     /** If true, high-frequency GCs will use a longer mark slice. */
    1840             :     JSGC_DYNAMIC_MARK_SLICE = 18,
    1841             : 
    1842             :     /** Lower limit after which we limit the heap growth. */
    1843             :     JSGC_ALLOCATION_THRESHOLD = 19,
    1844             : 
    1845             :     /**
    1846             :      * We try to keep at least this many unused chunks in the free chunk pool at
    1847             :      * all times, even after a shrinking GC.
    1848             :      */
    1849             :     JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
    1850             : 
    1851             :     /** We never keep more than this many unused chunks in the free chunk pool. */
    1852             :     JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
    1853             : 
    1854             :     /** Whether compacting GC is enabled. */
    1855             :     JSGC_COMPACTING_ENABLED = 23,
    1856             : 
    1857             :     /** If true, painting can trigger IGC slices. */
    1858             :     JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
    1859             : } JSGCParamKey;
    1860             : 
    1861             : extern JS_PUBLIC_API(void)
    1862             : JS_SetGCParameter(JSContext* cx, JSGCParamKey key, uint32_t value);
    1863             : 
    1864             : extern JS_PUBLIC_API(uint32_t)
    1865             : JS_GetGCParameter(JSContext* cx, JSGCParamKey key);
    1866             : 
    1867             : extern JS_PUBLIC_API(void)
    1868             : JS_SetGCParametersBasedOnAvailableMemory(JSContext* cx, uint32_t availMem);
    1869             : 
    1870             : /**
    1871             :  * Create a new JSString whose chars member refers to external memory, i.e.,
    1872             :  * memory requiring application-specific finalization.
    1873             :  */
    1874             : extern JS_PUBLIC_API(JSString*)
    1875             : JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
    1876             :                      const JSStringFinalizer* fin);
    1877             : 
    1878             : /**
    1879             :  * Create a new JSString whose chars member may refer to external memory.
    1880             :  * If a new external string is allocated, |*allocatedExternal| is set to true.
    1881             :  * Otherwise the returned string is either not an external string or an
    1882             :  * external string allocated by a previous call and |*allocatedExternal| is set
    1883             :  * to false. If |*allocatedExternal| is false, |fin| won't be called.
    1884             :  */
    1885             : extern JS_PUBLIC_API(JSString*)
    1886             : JS_NewMaybeExternalString(JSContext* cx, const char16_t* chars, size_t length,
    1887             :                           const JSStringFinalizer* fin, bool* allocatedExternal);
    1888             : 
    1889             : /**
    1890             :  * Return whether 'str' was created with JS_NewExternalString or
    1891             :  * JS_NewExternalStringWithClosure.
    1892             :  */
    1893             : extern JS_PUBLIC_API(bool)
    1894             : JS_IsExternalString(JSString* str);
    1895             : 
    1896             : /**
    1897             :  * Return the 'fin' arg passed to JS_NewExternalString.
    1898             :  */
    1899             : extern JS_PUBLIC_API(const JSStringFinalizer*)
    1900             : JS_GetExternalStringFinalizer(JSString* str);
    1901             : 
    1902             : /**
    1903             :  * Set the size of the native stack that should not be exceed. To disable
    1904             :  * stack size checking pass 0.
    1905             :  *
    1906             :  * SpiderMonkey allows for a distinction between system code (such as GCs, which
    1907             :  * may incidentally be triggered by script but are not strictly performed on
    1908             :  * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
    1909             :  * and untrusted script. Each kind of code may have a different stack quota,
    1910             :  * allowing embedders to keep higher-priority machinery running in the face of
    1911             :  * scripted stack exhaustion by something else.
    1912             :  *
    1913             :  * The stack quotas for each kind of code should be monotonically descending,
    1914             :  * and may be specified with this function. If 0 is passed for a given kind
    1915             :  * of code, it defaults to the value of the next-highest-priority kind.
    1916             :  *
    1917             :  * This function may only be called immediately after the runtime is initialized
    1918             :  * and before any code is executed and/or interrupts requested.
    1919             :  */
    1920             : extern JS_PUBLIC_API(void)
    1921             : JS_SetNativeStackQuota(JSContext* cx, size_t systemCodeStackSize,
    1922             :                        size_t trustedScriptStackSize = 0,
    1923             :                        size_t untrustedScriptStackSize = 0);
    1924             : 
    1925             : /************************************************************************/
    1926             : 
    1927             : extern JS_PUBLIC_API(bool)
    1928             : JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp);
    1929             : 
    1930             : extern JS_PUBLIC_API(bool)
    1931             : JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp);
    1932             : 
    1933             : extern JS_PUBLIC_API(bool)
    1934             : JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle<JS::Value> vp);
    1935             : 
    1936             : namespace JS {
    1937             : 
    1938             : /**
    1939             :  * Convert obj to a primitive value. On success, store the result in vp and
    1940             :  * return true.
    1941             :  *
    1942             :  * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or
    1943             :  * JSTYPE_UNDEFINED (no hint).
    1944             :  *
    1945             :  * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
    1946             :  */
    1947             : extern JS_PUBLIC_API(bool)
    1948             : ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);
    1949             : 
    1950             : /**
    1951             :  * If args.get(0) is one of the strings "string", "number", or "default", set
    1952             :  * result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_UNDEFINED accordingly and
    1953             :  * return true. Otherwise, return false with a TypeError pending.
    1954             :  *
    1955             :  * This can be useful in implementing a @@toPrimitive method.
    1956             :  */
    1957             : extern JS_PUBLIC_API(bool)
    1958             : GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result);
    1959             : 
    1960             : } /* namespace JS */
    1961             : 
    1962             : extern JS_PUBLIC_API(bool)
    1963             : JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    1964             :                 JS::MutableHandleValue vp);
    1965             : 
    1966             : extern JS_PUBLIC_API(bool)
    1967             : JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    1968             :                       JS::MutableHandleValue vp, JS::ObjectOpResult& result);
    1969             : 
    1970             : template<typename T>
    1971             : struct JSConstScalarSpec {
    1972             :     const char* name;
    1973             :     T val;
    1974             : };
    1975             : 
    1976             : typedef JSConstScalarSpec<double> JSConstDoubleSpec;
    1977             : typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
    1978             : 
    1979             : struct JSJitInfo;
    1980             : 
    1981             : /**
    1982             :  * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will
    1983             :  * allow us to pass one JSJitInfo per function with the property/function spec,
    1984             :  * without additional field overhead.
    1985             :  */
    1986             : struct JSNativeWrapper {
    1987             :     JSNative        op;
    1988             :     const JSJitInfo* info;
    1989             : };
    1990             : 
    1991             : /*
    1992             :  * Macro static initializers which make it easy to pass no JSJitInfo as part of a
    1993             :  * JSPropertySpec or JSFunctionSpec.
    1994             :  */
    1995             : #define JSNATIVE_WRAPPER(native) { {native, nullptr} }
    1996             : 
    1997             : /**
    1998             :  * Description of a property. JS_DefineProperties and JS_InitClass take arrays
    1999             :  * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END
    2000             :  * are helper macros for defining such arrays.
    2001             :  */
    2002             : struct JSPropertySpec {
    2003             :     struct SelfHostedWrapper {
    2004             :         void*       unused;
    2005             :         const char* funname;
    2006             :     };
    2007             : 
    2008             :     struct ValueWrapper {
    2009             :         uintptr_t   type;
    2010             :         union {
    2011             :             const char* string;
    2012             :             int32_t     int32;
    2013             :         };
    2014             :     };
    2015             : 
    2016             :     const char*                 name;
    2017             :     uint8_t                     flags;
    2018             :     union {
    2019             :         struct {
    2020             :             union {
    2021             :                 JSNativeWrapper    native;
    2022             :                 SelfHostedWrapper  selfHosted;
    2023             :             } getter;
    2024             :             union {
    2025             :                 JSNativeWrapper    native;
    2026             :                 SelfHostedWrapper  selfHosted;
    2027             :             } setter;
    2028             :         } accessors;
    2029             :         ValueWrapper            value;
    2030             :     };
    2031             : 
    2032       21412 :     bool isAccessor() const {
    2033       21412 :         return !(flags & JSPROP_INTERNAL_USE_BIT);
    2034             :     }
    2035             :     JS_PUBLIC_API(bool) getValue(JSContext* cx, JS::MutableHandleValue value) const;
    2036             : 
    2037       10233 :     bool isSelfHosted() const {
    2038       10233 :         MOZ_ASSERT(isAccessor());
    2039             : 
    2040             : #ifdef DEBUG
    2041             :         // Verify that our accessors match our JSPROP_GETTER flag.
    2042       10233 :         if (flags & JSPROP_GETTER)
    2043         663 :             checkAccessorsAreSelfHosted();
    2044             :         else
    2045        9570 :             checkAccessorsAreNative();
    2046             : #endif
    2047       10233 :         return (flags & JSPROP_GETTER);
    2048             :     }
    2049             : 
    2050             :     static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper),
    2051             :                   "JSPropertySpec::getter/setter must be compact");
    2052             :     static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info),
    2053             :                   "JS_SELF_HOSTED* macros below require that "
    2054             :                   "SelfHostedWrapper::funname overlay "
    2055             :                   "JSNativeWrapper::info");
    2056             : private:
    2057        9570 :     void checkAccessorsAreNative() const {
    2058        9570 :         MOZ_ASSERT(accessors.getter.native.op);
    2059             :         // We may not have a setter at all.  So all we can assert here, for the
    2060             :         // native case is that if we have a jitinfo for the setter then we have
    2061             :         // a setter op too.  This is good enough to make sure we don't have a
    2062             :         // SelfHostedWrapper for the setter.
    2063        9570 :         MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
    2064        9570 :     }
    2065             : 
    2066         663 :     void checkAccessorsAreSelfHosted() const {
    2067         663 :         MOZ_ASSERT(!accessors.getter.selfHosted.unused);
    2068         663 :         MOZ_ASSERT(!accessors.setter.selfHosted.unused);
    2069         663 :     }
    2070             : };
    2071             : 
    2072             : namespace JS {
    2073             : namespace detail {
    2074             : 
    2075             : /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_NATIVE_TO only. */
    2076             : inline int CheckIsNative(JSNative native);
    2077             : 
    2078             : /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_STRING_TO only. */
    2079             : template<size_t N>
    2080             : inline int
    2081             : CheckIsCharacterLiteral(const char (&arr)[N]);
    2082             : 
    2083             : /* NEVER DEFINED, DON'T USE.  For use by JS_CAST_INT32_TO only. */
    2084             : inline int CheckIsInt32(int32_t value);
    2085             : 
    2086             : /* NEVER DEFINED, DON'T USE.  For use by JS_PROPERTYOP_GETTER only. */
    2087             : inline int CheckIsGetterOp(JSGetterOp op);
    2088             : 
    2089             : /* NEVER DEFINED, DON'T USE.  For use by JS_PROPERTYOP_SETTER only. */
    2090             : inline int CheckIsSetterOp(JSSetterOp op);
    2091             : 
    2092             : } // namespace detail
    2093             : } // namespace JS
    2094             : 
    2095             : #define JS_CAST_NATIVE_TO(v, To) \
    2096             :   (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
    2097             :    reinterpret_cast<To>(v))
    2098             : 
    2099             : #define JS_CAST_STRING_TO(s, To) \
    2100             :   (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
    2101             :    reinterpret_cast<To>(s))
    2102             : 
    2103             : #define JS_CAST_INT32_TO(s, To) \
    2104             :   (static_cast<void>(sizeof(JS::detail::CheckIsInt32(s))), \
    2105             :    reinterpret_cast<To>(s))
    2106             : 
    2107             : #define JS_CHECK_ACCESSOR_FLAGS(flags) \
    2108             :   (static_cast<mozilla::EnableIf<((flags) & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT)) == 0>::Type>(0), \
    2109             :    (flags))
    2110             : 
    2111             : #define JS_PROPERTYOP_GETTER(v) \
    2112             :   (static_cast<void>(sizeof(JS::detail::CheckIsGetterOp(v))), \
    2113             :    reinterpret_cast<JSNative>(v))
    2114             : 
    2115             : #define JS_PROPERTYOP_SETTER(v) \
    2116             :   (static_cast<void>(sizeof(JS::detail::CheckIsSetterOp(v))), \
    2117             :    reinterpret_cast<JSNative>(v))
    2118             : 
    2119             : #define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub)
    2120             : 
    2121             : #define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
    2122             : 
    2123             : #define JS_PS_ACCESSOR_SPEC(name, getter, setter, flags, extraFlags) \
    2124             :     { name, uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | extraFlags), \
    2125             :       { {  getter, setter  } } }
    2126             : #define JS_PS_VALUE_SPEC(name, value, flags) \
    2127             :     { name, uint8_t(flags | JSPROP_INTERNAL_USE_BIT), \
    2128             :       { { value, JSNATIVE_WRAPPER(nullptr) } } }
    2129             : 
    2130             : #define SELFHOSTED_WRAPPER(name) \
    2131             :     { { nullptr, JS_CAST_STRING_TO(name, const JSJitInfo*) } }
    2132             : #define STRINGVALUE_WRAPPER(value) \
    2133             :     { { reinterpret_cast<JSNative>(JSVAL_TYPE_STRING), JS_CAST_STRING_TO(value, const JSJitInfo*) } }
    2134             : #define INT32VALUE_WRAPPER(value) \
    2135             :     { { reinterpret_cast<JSNative>(JSVAL_TYPE_INT32), JS_CAST_INT32_TO(value, const JSJitInfo*) } }
    2136             : 
    2137             : /*
    2138             :  * JSPropertySpec uses JSNativeWrapper.  These macros encapsulate the definition
    2139             :  * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
    2140             :  * them.
    2141             :  */
    2142             : #define JS_PSG(name, getter, flags) \
    2143             :     JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(nullptr), flags, \
    2144             :                         JSPROP_SHARED)
    2145             : #define JS_PSGS(name, getter, setter, flags) \
    2146             :     JS_PS_ACCESSOR_SPEC(name, JSNATIVE_WRAPPER(getter), JSNATIVE_WRAPPER(setter), flags, \
    2147             :                          JSPROP_SHARED)
    2148             : #define JS_SELF_HOSTED_GET(name, getterName, flags) \
    2149             :     JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
    2150             :                          JSPROP_SHARED | JSPROP_GETTER)
    2151             : #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
    2152             :     JS_PS_ACCESSOR_SPEC(name, SELFHOSTED_WRAPPER(getterName), SELFHOSTED_WRAPPER(setterName), \
    2153             :                          flags, JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER)
    2154             : #define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
    2155             :     JS_PS_ACCESSOR_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
    2156             :                          SELFHOSTED_WRAPPER(getterName), JSNATIVE_WRAPPER(nullptr), flags, \
    2157             :                          JSPROP_SHARED | JSPROP_GETTER)
    2158             : #define JS_STRING_PS(name, string, flags) \
    2159             :     JS_PS_VALUE_SPEC(name, STRINGVALUE_WRAPPER(string), flags)
    2160             : #define JS_STRING_SYM_PS(symbol, string, flags) \
    2161             :     JS_PS_VALUE_SPEC(reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
    2162             :                      STRINGVALUE_WRAPPER(string), flags)
    2163             : #define JS_INT32_PS(name, value, flags) \
    2164             :     JS_PS_VALUE_SPEC(name, INT32VALUE_WRAPPER(value), flags)
    2165             : #define JS_PS_END \
    2166             :     JS_PS_ACCESSOR_SPEC(nullptr, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr), 0, 0)
    2167             : 
    2168             : /**
    2169             :  * To define a native function, set call to a JSNativeWrapper. To define a
    2170             :  * self-hosted function, set selfHostedName to the name of a function
    2171             :  * compiled during JSRuntime::initSelfHosting.
    2172             :  */
    2173             : struct JSFunctionSpec {
    2174             :     const char*     name;
    2175             :     JSNativeWrapper call;
    2176             :     uint16_t        nargs;
    2177             :     uint16_t        flags;
    2178             :     const char*     selfHostedName;
    2179             : };
    2180             : 
    2181             : /*
    2182             :  * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
    2183             :  * that's passed to JS_DefineFunctions or JS_InitClass.
    2184             :  */
    2185             : #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
    2186             : 
    2187             : /*
    2188             :  * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
    2189             :  * homage to the old JSNative/JSFastNative split) simply adds the flag
    2190             :  * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
    2191             :  * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function.
    2192             :  * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives
    2193             :  * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the
    2194             :  * fields.
    2195             :  *
    2196             :  * The _SYM variants allow defining a function with a symbol key rather than a
    2197             :  * string key. For example, use JS_SYM_FN(iterator, ...) to define an
    2198             :  * @@iterator method.
    2199             :  */
    2200             : #define JS_FS(name,call,nargs,flags)                                          \
    2201             :     JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
    2202             : #define JS_FN(name,call,nargs,flags)                                          \
    2203             :     JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
    2204             : #define JS_INLINABLE_FN(name,call,nargs,flags,native)                         \
    2205             :     JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
    2206             : #define JS_SYM_FN(symbol,call,nargs,flags)                                    \
    2207             :     JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
    2208             : #define JS_FNINFO(name,call,info,nargs,flags)                                 \
    2209             :     JS_FNSPEC(name, call, info, nargs, flags, nullptr)
    2210             : #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags)                    \
    2211             :     JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
    2212             : #define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags)           \
    2213             :     JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
    2214             : #define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName)       \
    2215             :     JS_FNSPEC(reinterpret_cast<const char*>(                                 \
    2216             :                   uint32_t(::JS::SymbolCode::symbol) + 1),                    \
    2217             :               call, info, nargs, flags, selfHostedName)
    2218             : #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName)                  \
    2219             :     {name, {call, info}, nargs, flags, selfHostedName}
    2220             : 
    2221             : extern JS_PUBLIC_API(JSObject*)
    2222             : JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto,
    2223             :              const JSClass* clasp, JSNative constructor, unsigned nargs,
    2224             :              const JSPropertySpec* ps, const JSFunctionSpec* fs,
    2225             :              const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
    2226             : 
    2227             : /**
    2228             :  * Set up ctor.prototype = proto and proto.constructor = ctor with the
    2229             :  * right property flags.
    2230             :  */
    2231             : extern JS_PUBLIC_API(bool)
    2232             : JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle<JSObject*> ctor,
    2233             :                                JS::Handle<JSObject*> proto);
    2234             : 
    2235             : extern JS_PUBLIC_API(const JSClass*)
    2236             : JS_GetClass(JSObject* obj);
    2237             : 
    2238             : extern JS_PUBLIC_API(bool)
    2239             : JS_InstanceOf(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp, JS::CallArgs* args);
    2240             : 
    2241             : extern JS_PUBLIC_API(bool)
    2242             : JS_HasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool* bp);
    2243             : 
    2244             : namespace JS {
    2245             : 
    2246             : // Implementation of
    2247             : // http://www.ecma-international.org/ecma-262/6.0/#sec-ordinaryhasinstance.  If
    2248             : // you're looking for the equivalent of "instanceof", you want JS_HasInstance,
    2249             : // not this function.
    2250             : extern JS_PUBLIC_API(bool)
    2251             : OrdinaryHasInstance(JSContext* cx, HandleObject objArg, HandleValue v, bool* bp);
    2252             : 
    2253             : } // namespace JS
    2254             : 
    2255             : extern JS_PUBLIC_API(void*)
    2256             : JS_GetPrivate(JSObject* obj);
    2257             : 
    2258             : extern JS_PUBLIC_API(void)
    2259             : JS_SetPrivate(JSObject* obj, void* data);
    2260             : 
    2261             : extern JS_PUBLIC_API(void*)
    2262             : JS_GetInstancePrivate(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp,
    2263             :                       JS::CallArgs* args);
    2264             : 
    2265             : extern JS_PUBLIC_API(JSObject*)
    2266             : JS_GetConstructor(JSContext* cx, JS::Handle<JSObject*> proto);
    2267             : 
    2268             : namespace JS {
    2269             : 
    2270             : // Specification for which zone a newly created compartment should use.
    2271             : enum ZoneSpecifier {
    2272             :     // Use the single runtime wide system zone. The meaning of this zone is
    2273             :     // left to the embedder.
    2274             :     SystemZone,
    2275             : 
    2276             :     // Use a particular existing zone.
    2277             :     ExistingZone,
    2278             : 
    2279             :     // Create a new zone with its own new zone group.
    2280             :     NewZoneInNewZoneGroup,
    2281             : 
    2282             :     // Create a new zone in the same zone group as the system zone.
    2283             :     NewZoneInSystemZoneGroup,
    2284             : 
    2285             :     // Create a new zone in the same zone group as another existing zone.
    2286             :     NewZoneInExistingZoneGroup
    2287             : };
    2288             : 
    2289             : /**
    2290             :  * CompartmentCreationOptions specifies options relevant to creating a new
    2291             :  * compartment, that are either immutable characteristics of that compartment
    2292             :  * or that are discarded after the compartment has been created.
    2293             :  *
    2294             :  * Access to these options on an existing compartment is read-only: if you
    2295             :  * need particular selections, make them before you create the compartment.
    2296             :  */
    2297             : class JS_PUBLIC_API(CompartmentCreationOptions)
    2298             : {
    2299             :   public:
    2300         319 :     CompartmentCreationOptions()
    2301         319 :       : addonId_(nullptr),
    2302             :         traceGlobal_(nullptr),
    2303             :         zoneSpec_(NewZoneInSystemZoneGroup),
    2304             :         zonePointer_(nullptr),
    2305             :         invisibleToDebugger_(false),
    2306             :         mergeable_(false),
    2307             :         preserveJitCode_(false),
    2308             :         cloneSingletons_(false),
    2309             :         experimentalNumberFormatFormatToPartsEnabled_(false),
    2310             :         sharedMemoryAndAtomics_(false),
    2311         319 :         secureContext_(false)
    2312         319 :     {}
    2313             : 
    2314             :     // A null add-on ID means that the compartment is not associated with an
    2315             :     // add-on.
    2316       21597 :     JSAddonId* addonIdOrNull() const { return addonId_; }
    2317         283 :     CompartmentCreationOptions& setAddonId(JSAddonId* id) {
    2318         283 :         addonId_ = id;
    2319         283 :         return *this;
    2320             :     }
    2321             : 
    2322          26 :     JSTraceOp getTrace() const {
    2323          26 :         return traceGlobal_;
    2324             :     }
    2325         310 :     CompartmentCreationOptions& setTrace(JSTraceOp op) {
    2326         310 :         traceGlobal_ = op;
    2327         310 :         return *this;
    2328             :     }
    2329             : 
    2330           3 :     void* zonePointer() const { return zonePointer_; }
    2331         311 :     ZoneSpecifier zoneSpecifier() const { return zoneSpec_; }
    2332             : 
    2333             :     // Set the zone to use for the compartment. See ZoneSpecifier above.
    2334             :     CompartmentCreationOptions& setSystemZone();
    2335             :     CompartmentCreationOptions& setExistingZone(JSObject* obj);
    2336             :     CompartmentCreationOptions& setNewZoneInNewZoneGroup();
    2337             :     CompartmentCreationOptions& setNewZoneInSystemZoneGroup();
    2338             :     CompartmentCreationOptions& setNewZoneInExistingZoneGroup(JSObject* obj);
    2339             : 
    2340             :     // Certain scopes (i.e. XBL compilation scopes) are implementation details
    2341             :     // of the embedding, and references to them should never leak out to script.
    2342             :     // This flag causes the this compartment to skip firing onNewGlobalObject
    2343             :     // and makes addDebuggee a no-op for this global.
    2344        2266 :     bool invisibleToDebugger() const { return invisibleToDebugger_; }
    2345          42 :     CompartmentCreationOptions& setInvisibleToDebugger(bool flag) {
    2346          42 :         invisibleToDebugger_ = flag;
    2347          42 :         return *this;
    2348             :     }
    2349             : 
    2350             :     // Compartments used for off-thread compilation have their contents merged
    2351             :     // into a target compartment when the compilation is finished. This is only
    2352             :     // allowed if this flag is set. The invisibleToDebugger flag must also be
    2353             :     // set for such compartments.
    2354         330 :     bool mergeable() const { return mergeable_; }
    2355          16 :     CompartmentCreationOptions& setMergeable(bool flag) {
    2356          16 :         mergeable_ = flag;
    2357          16 :         return *this;
    2358             :     }
    2359             : 
    2360             :     // Determines whether this compartment should preserve JIT code on
    2361             :     // non-shrinking GCs.
    2362         223 :     bool preserveJitCode() const { return preserveJitCode_; }
    2363             :     CompartmentCreationOptions& setPreserveJitCode(bool flag) {
    2364             :         preserveJitCode_ = flag;
    2365             :         return *this;
    2366             :     }
    2367             : 
    2368         186 :     bool cloneSingletons() const { return cloneSingletons_; }
    2369             :     CompartmentCreationOptions& setCloneSingletons(bool flag) {
    2370             :         cloneSingletons_ = flag;
    2371             :         return *this;
    2372             :     }
    2373             : 
    2374             :     // ECMA-402 is considering adding a "formatToParts" NumberFormat method,
    2375             :     // that exposes not just a formatted string but its subcomponents.  The
    2376             :     // method, its semantics, and its name aren't finalized, so for now it's
    2377             :     // exposed *only* if requested.
    2378             :     //
    2379             :     // Until "formatToParts" is included in a final specification edition, it's
    2380             :     // subject to change or removal at any time.  Do *not* rely on it in
    2381             :     // mission-critical code that can't be changed if ECMA-402 decides not to
    2382             :     // accept the method in its current form.
    2383           6 :     bool experimentalNumberFormatFormatToPartsEnabled() const {
    2384           6 :         return experimentalNumberFormatFormatToPartsEnabled_;
    2385             :     }
    2386             :     CompartmentCreationOptions& setExperimentalNumberFormatFormatToPartsEnabled(bool flag) {
    2387             :         experimentalNumberFormatFormatToPartsEnabled_ = flag;
    2388             :         return *this;
    2389             :     }
    2390             : 
    2391             :     bool getSharedMemoryAndAtomicsEnabled() const;
    2392             :     CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
    2393             : 
    2394             :     // This flag doesn't affect JS engine behavior.  It is used by Gecko to
    2395             :     // mark whether content windows and workers are "Secure Context"s. See
    2396             :     // https://w3c.github.io/webappsec-secure-contexts/
    2397             :     // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
    2398           4 :     bool secureContext() const { return secureContext_; }
    2399         272 :     CompartmentCreationOptions& setSecureContext(bool flag) {
    2400         272 :         secureContext_ = flag;
    2401         272 :         return *this;
    2402             :     }
    2403             : 
    2404             :   private:
    2405             :     JSAddonId* addonId_;
    2406             :     JSTraceOp traceGlobal_;
    2407             :     ZoneSpecifier zoneSpec_;
    2408             :     void* zonePointer_; // Per zoneSpec_, either a Zone, ZoneGroup, or null.
    2409             :     bool invisibleToDebugger_;
    2410             :     bool mergeable_;
    2411             :     bool preserveJitCode_;
    2412             :     bool cloneSingletons_;
    2413             :     bool experimentalNumberFormatFormatToPartsEnabled_;
    2414             :     bool sharedMemoryAndAtomics_;
    2415             :     bool secureContext_;
    2416             : };
    2417             : 
    2418             : /**
    2419             :  * CompartmentBehaviors specifies behaviors of a compartment that can be
    2420             :  * changed after the compartment's been created.
    2421             :  */
    2422             : class JS_PUBLIC_API(CompartmentBehaviors)
    2423             : {
    2424             :   public:
    2425             :     class Override {
    2426             :       public:
    2427         312 :         Override() : mode_(Default) {}
    2428             : 
    2429       25205 :         bool get(bool defaultValue) const {
    2430       25205 :             if (mode_ == Default)
    2431       25171 :                 return defaultValue;
    2432          34 :             return mode_ == ForceTrue;
    2433             :         }
    2434             : 
    2435           1 :         void set(bool overrideValue) {
    2436           1 :             mode_ = overrideValue ? ForceTrue : ForceFalse;
    2437           1 :         }
    2438             : 
    2439             :         void reset() {
    2440             :             mode_ = Default;
    2441             :         }
    2442             : 
    2443             :       private:
    2444             :         enum Mode {
    2445             :             Default,
    2446             :             ForceTrue,
    2447             :             ForceFalse
    2448             :         };
    2449             : 
    2450             :         Mode mode_;
    2451             :     };
    2452             : 
    2453         312 :     CompartmentBehaviors()
    2454         312 :       : version_(JSVERSION_UNKNOWN)
    2455             :       , discardSource_(false)
    2456             :       , disableLazyParsing_(false)
    2457         312 :       , singletonsAsTemplates_(true)
    2458             :     {
    2459         312 :     }
    2460             : 
    2461        5570 :     JSVersion version() const { return version_; }
    2462         262 :     CompartmentBehaviors& setVersion(JSVersion aVersion) {
    2463         262 :         MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
    2464         262 :         version_ = aVersion;
    2465         262 :         return *this;
    2466             :     }
    2467             : 
    2468             :     // For certain globals, we know enough about the code that will run in them
    2469             :     // that we can discard script source entirely.
    2470         561 :     bool discardSource() const { return discardSource_; }
    2471          29 :     CompartmentBehaviors& setDiscardSource(bool flag) {
    2472          29 :         discardSource_ = flag;
    2473          29 :         return *this;
    2474             :     }
    2475             : 
    2476         277 :     bool disableLazyParsing() const { return disableLazyParsing_; }
    2477           0 :     CompartmentBehaviors& setDisableLazyParsing(bool flag) {
    2478           0 :         disableLazyParsing_ = flag;
    2479           0 :         return *this;
    2480             :     }
    2481             : 
    2482             :     bool extraWarnings(JSContext* cx) const;
    2483           1 :     Override& extraWarningsOverride() { return extraWarningsOverride_; }
    2484             : 
    2485           0 :     bool getSingletonsAsTemplates() const {
    2486           0 :         return singletonsAsTemplates_;
    2487             :     }
    2488          40 :     CompartmentBehaviors& setSingletonsAsValues() {
    2489          40 :         singletonsAsTemplates_ = false;
    2490          40 :         return *this;
    2491             :     }
    2492             : 
    2493             :   private:
    2494             :     JSVersion version_;
    2495             :     bool discardSource_;
    2496             :     bool disableLazyParsing_;
    2497             :     Override extraWarningsOverride_;
    2498             : 
    2499             :     // To XDR singletons, we need to ensure that all singletons are all used as
    2500             :     // templates, by making JSOP_OBJECT return a clone of the JSScript
    2501             :     // singleton, instead of returning the value which is baked in the JSScript.
    2502             :     bool singletonsAsTemplates_;
    2503             : };
    2504             : 
    2505             : /**
    2506             :  * CompartmentOptions specifies compartment characteristics: both those that
    2507             :  * can't be changed on a compartment once it's been created
    2508             :  * (CompartmentCreationOptions), and those that can be changed on an existing
    2509             :  * compartment (CompartmentBehaviors).
    2510             :  */
    2511             : class JS_PUBLIC_API(CompartmentOptions)
    2512             : {
    2513             :   public:
    2514         312 :     explicit CompartmentOptions()
    2515         312 :       : creationOptions_(),
    2516         312 :         behaviors_()
    2517         312 :     {}
    2518             : 
    2519          16 :     CompartmentOptions(const CompartmentCreationOptions& compartmentCreation,
    2520             :                        const CompartmentBehaviors& compartmentBehaviors)
    2521          16 :       : creationOptions_(compartmentCreation),
    2522          16 :         behaviors_(compartmentBehaviors)
    2523          16 :     {}
    2524             : 
    2525             :     // CompartmentCreationOptions specify fundamental compartment
    2526             :     // characteristics that must be specified when the compartment is created,
    2527             :     // that can't be changed after the compartment is created.
    2528        1390 :     CompartmentCreationOptions& creationOptions() {
    2529        1390 :         return creationOptions_;
    2530             :     }
    2531         629 :     const CompartmentCreationOptions& creationOptions() const {
    2532         629 :         return creationOptions_;
    2533             :     }
    2534             : 
    2535             :     // CompartmentBehaviors specify compartment characteristics that can be
    2536             :     // changed after the compartment is created.
    2537         291 :     CompartmentBehaviors& behaviors() {
    2538         291 :         return behaviors_;
    2539             :     }
    2540         315 :     const CompartmentBehaviors& behaviors() const {
    2541         315 :         return behaviors_;
    2542             :     }
    2543             : 
    2544             :   private:
    2545             :     CompartmentCreationOptions creationOptions_;
    2546             :     CompartmentBehaviors behaviors_;
    2547             : };
    2548             : 
    2549             : JS_PUBLIC_API(const CompartmentCreationOptions&)
    2550             : CompartmentCreationOptionsRef(JSCompartment* compartment);
    2551             : 
    2552             : JS_PUBLIC_API(const CompartmentCreationOptions&)
    2553             : CompartmentCreationOptionsRef(JSObject* obj);
    2554             : 
    2555             : JS_PUBLIC_API(const CompartmentCreationOptions&)
    2556             : CompartmentCreationOptionsRef(JSContext* cx);
    2557             : 
    2558             : JS_PUBLIC_API(CompartmentBehaviors&)
    2559             : CompartmentBehaviorsRef(JSCompartment* compartment);
    2560             : 
    2561             : JS_PUBLIC_API(CompartmentBehaviors&)
    2562             : CompartmentBehaviorsRef(JSObject* obj);
    2563             : 
    2564             : JS_PUBLIC_API(CompartmentBehaviors&)
    2565             : CompartmentBehaviorsRef(JSContext* cx);
    2566             : 
    2567             : /**
    2568             :  * During global creation, we fire notifications to callbacks registered
    2569             :  * via the Debugger API. These callbacks are arbitrary script, and can touch
    2570             :  * the global in arbitrary ways. When that happens, the global should not be
    2571             :  * in a half-baked state. But this creates a problem for consumers that need
    2572             :  * to set slots on the global to put it in a consistent state.
    2573             :  *
    2574             :  * This API provides a way for consumers to set slots atomically (immediately
    2575             :  * after the global is created), before any debugger hooks are fired. It's
    2576             :  * unfortunately on the clunky side, but that's the way the cookie crumbles.
    2577             :  *
    2578             :  * If callers have no additional state on the global to set up, they may pass
    2579             :  * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
    2580             :  * fire the hook as its final act before returning. Otherwise, callers should
    2581             :  * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
    2582             :  * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
    2583             :  * an error occurs and the operation aborts, callers should skip firing the
    2584             :  * hook. But otherwise, callers must take care to fire the hook exactly once
    2585             :  * before compiling any script in the global's scope (we have assertions in
    2586             :  * place to enforce this). This lets us be sure that debugger clients never miss
    2587             :  * breakpoints.
    2588             :  */
    2589             : enum OnNewGlobalHookOption {
    2590             :     FireOnNewGlobalHook,
    2591             :     DontFireOnNewGlobalHook
    2592             : };
    2593             : 
    2594             : } /* namespace JS */
    2595             : 
    2596             : extern JS_PUBLIC_API(JSObject*)
    2597             : JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
    2598             :                    JS::OnNewGlobalHookOption hookOption,
    2599             :                    const JS::CompartmentOptions& options);
    2600             : /**
    2601             :  * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
    2602             :  * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
    2603             :  * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
    2604             :  * object, from which we can be sure the compartment is relevant, and mark it.
    2605             :  *
    2606             :  * It is still possible to specify custom trace hooks for global object classes. They can be
    2607             :  * provided via the CompartmentOptions passed to JS_NewGlobalObject.
    2608             :  */
    2609             : extern JS_PUBLIC_API(void)
    2610             : JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global);
    2611             : 
    2612             : extern JS_PUBLIC_API(void)
    2613             : JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global);
    2614             : 
    2615             : extern JS_PUBLIC_API(JSObject*)
    2616             : JS_NewObject(JSContext* cx, const JSClass* clasp);
    2617             : 
    2618             : extern JS_PUBLIC_API(bool)
    2619             : JS_IsNative(JSObject* obj);
    2620             : 
    2621             : /**
    2622             :  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
    2623             :  * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
    2624             :  */
    2625             : extern JS_PUBLIC_API(JSObject*)
    2626             : JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
    2627             : 
    2628             : /** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */
    2629             : extern JS_PUBLIC_API(JSObject*)
    2630             : JS_NewPlainObject(JSContext* cx);
    2631             : 
    2632             : /**
    2633             :  * Freeze obj, and all objects it refers to, recursively. This will not recurse
    2634             :  * through non-extensible objects, on the assumption that those are already
    2635             :  * deep-frozen.
    2636             :  */
    2637             : extern JS_PUBLIC_API(bool)
    2638             : JS_DeepFreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
    2639             : 
    2640             : /**
    2641             :  * Freezes an object; see ES5's Object.freeze(obj) method.
    2642             :  */
    2643             : extern JS_PUBLIC_API(bool)
    2644             : JS_FreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
    2645             : 
    2646             : 
    2647             : /*** Property descriptors ************************************************************************/
    2648             : 
    2649             : namespace JS {
    2650             : 
    2651             : struct JS_PUBLIC_API(PropertyDescriptor) {
    2652             :     JSObject* obj;
    2653             :     unsigned attrs;
    2654             :     JSGetterOp getter;
    2655             :     JSSetterOp setter;
    2656             :     JS::Value value;
    2657             : 
    2658      145336 :     PropertyDescriptor()
    2659      145336 :       : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue())
    2660      145336 :     {}
    2661             : 
    2662             :     static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); }
    2663             :     void trace(JSTracer* trc);
    2664             : };
    2665             : 
    2666             : } // namespace JS
    2667             : 
    2668             : namespace js {
    2669             : 
    2670             : template <typename Wrapper>
    2671      681738 : class WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
    2672             : {
    2673     9499600 :     const JS::PropertyDescriptor& desc() const { return static_cast<const Wrapper*>(this)->get(); }
    2674             : 
    2675     4046928 :     bool has(unsigned bit) const {
    2676     4046928 :         MOZ_ASSERT(bit != 0);
    2677     4046928 :         MOZ_ASSERT((bit & (bit - 1)) == 0);  // only a single bit
    2678     4046928 :         return (desc().attrs & bit) != 0;
    2679             :     }
    2680             : 
    2681     1059395 :     bool hasAny(unsigned bits) const {
    2682     1059395 :         return (desc().attrs & bits) != 0;
    2683             :     }
    2684             : 
    2685     1448668 :     bool hasAll(unsigned bits) const {
    2686     1448668 :         return (desc().attrs & bits) == bits;
    2687             :     }
    2688             : 
    2689             :     // Non-API attributes bit used internally for arguments objects.
    2690             :     enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT };
    2691             : 
    2692             :   public:
    2693             :     // Descriptors with JSGetterOp/JSSetterOp are considered data
    2694             :     // descriptors. It's complicated.
    2695     1059392 :     bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); }
    2696      254281 :     bool isGenericDescriptor() const {
    2697      254281 :         return (desc().attrs&
    2698             :                 (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) ==
    2699      254281 :                (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE);
    2700             :     }
    2701      143720 :     bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); }
    2702             : 
    2703      147632 :     bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); }
    2704       10549 :     bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); }
    2705             : 
    2706       29381 :     bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); }
    2707       10129 :     bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); }
    2708             : 
    2709       19621 :     bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); }
    2710      338375 :     JS::HandleValue value() const {
    2711      338375 :         return JS::HandleValue::fromMarkedLocation(&desc().value);
    2712             :     }
    2713             : 
    2714      130108 :     bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); }
    2715        9530 :     bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); }
    2716             : 
    2717       20389 :     bool hasGetterObject() const { return has(JSPROP_GETTER); }
    2718         235 :     JS::HandleObject getterObject() const {
    2719         235 :         MOZ_ASSERT(hasGetterObject());
    2720         235 :         return JS::HandleObject::fromMarkedLocation(
    2721         470 :                 reinterpret_cast<JSObject* const*>(&desc().getter));
    2722             :     }
    2723       18834 :     bool hasSetterObject() const { return has(JSPROP_SETTER); }
    2724         191 :     JS::HandleObject setterObject() const {
    2725         191 :         MOZ_ASSERT(hasSetterObject());
    2726         191 :         return JS::HandleObject::fromMarkedLocation(
    2727         382 :                 reinterpret_cast<JSObject* const*>(&desc().setter));
    2728             :     }
    2729             : 
    2730          41 :     bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
    2731         511 :     bool isShared() const { return has(JSPROP_SHARED); }
    2732             : 
    2733        1110 :     JS::HandleObject object() const {
    2734        1110 :         return JS::HandleObject::fromMarkedLocation(&desc().obj);
    2735             :     }
    2736     1034348 :     unsigned attributes() const { return desc().attrs; }
    2737      639045 :     JSGetterOp getter() const { return desc().getter; }
    2738      660099 :     JSSetterOp setter() const { return desc().setter; }
    2739             : 
    2740      503804 :     void assertValid() const {
    2741             : #ifdef DEBUG
    2742      503804 :         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
    2743             :                                      JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
    2744             :                                      JSPROP_READONLY | JSPROP_IGNORE_READONLY |
    2745             :                                      JSPROP_IGNORE_VALUE |
    2746             :                                      JSPROP_GETTER |
    2747             :                                      JSPROP_SETTER |
    2748             :                                      JSPROP_SHARED |
    2749             :                                      JSPROP_REDEFINE_NONCONFIGURABLE |
    2750             :                                      JSPROP_RESOLVING |
    2751             :                                      SHADOWABLE)) == 0);
    2752      503804 :         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
    2753      503800 :         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
    2754      503797 :         if (isAccessorDescriptor()) {
    2755       62698 :             MOZ_ASSERT(has(JSPROP_SHARED));
    2756       62698 :             MOZ_ASSERT(!has(JSPROP_READONLY));
    2757       62698 :             MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
    2758       62698 :             MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
    2759       62698 :             MOZ_ASSERT(!has(SHADOWABLE));
    2760       62698 :             MOZ_ASSERT(value().isUndefined());
    2761       62698 :             MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
    2762       62698 :             MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
    2763             :         } else {
    2764      441101 :             MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
    2765      441101 :             MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
    2766             :         }
    2767      503800 :         MOZ_ASSERT(getter() != JS_PropertyStub);
    2768      503797 :         MOZ_ASSERT(setter() != JS_StrictPropertyStub);
    2769             : 
    2770      503796 :         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
    2771      503798 :         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
    2772      503801 :         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
    2773      503807 :         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
    2774      503807 :         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
    2775             : #endif
    2776      503805 :     }
    2777             : 
    2778      256161 :     void assertComplete() const {
    2779             : #ifdef DEBUG
    2780      256161 :         assertValid();
    2781      256162 :         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
    2782             :                                      JSPROP_PERMANENT |
    2783             :                                      JSPROP_READONLY |
    2784             :                                      JSPROP_GETTER |
    2785             :                                      JSPROP_SETTER |
    2786             :                                      JSPROP_SHARED |
    2787             :                                      JSPROP_REDEFINE_NONCONFIGURABLE |
    2788             :                                      JSPROP_RESOLVING |
    2789             :                                      SHADOWABLE)) == 0);
    2790      256162 :         MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
    2791             : #endif
    2792      256161 :     }
    2793             : 
    2794         582 :     void assertCompleteIfFound() const {
    2795             : #ifdef DEBUG
    2796         582 :         if (object())
    2797         326 :             assertComplete();
    2798             : #endif
    2799         582 :     }
    2800             : };
    2801             : 
    2802             : template <typename Wrapper>
    2803      409525 : class MutableWrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
    2804             :     : public js::WrappedPtrOperations<JS::PropertyDescriptor, Wrapper>
    2805             : {
    2806      990889 :     JS::PropertyDescriptor& desc() { return static_cast<Wrapper*>(this)->get(); }
    2807             : 
    2808             :   public:
    2809        2317 :     void clear() {
    2810        2317 :         object().set(nullptr);
    2811        2317 :         setAttributes(0);
    2812        2317 :         setGetter(nullptr);
    2813        2317 :         setSetter(nullptr);
    2814        2317 :         value().setUndefined();
    2815        2317 :     }
    2816             : 
    2817      129039 :     void initFields(JS::HandleObject obj, JS::HandleValue v, unsigned attrs,
    2818             :                     JSGetterOp getterOp, JSSetterOp setterOp) {
    2819      129039 :         MOZ_ASSERT(getterOp != JS_PropertyStub);
    2820      129039 :         MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
    2821             : 
    2822      129039 :         object().set(obj);
    2823      129039 :         value().set(v);
    2824      129039 :         setAttributes(attrs);
    2825      129039 :         setGetter(getterOp);
    2826      129039 :         setSetter(setterOp);
    2827      129038 :     }
    2828             : 
    2829          41 :     void assign(JS::PropertyDescriptor& other) {
    2830          41 :         object().set(other.obj);
    2831          41 :         setAttributes(other.attrs);
    2832          41 :         setGetter(other.getter);
    2833          41 :         setSetter(other.setter);
    2834          41 :         value().set(other.value);
    2835          41 :     }
    2836             : 
    2837           0 :     void setDataDescriptor(JS::HandleValue v, unsigned attrs) {
    2838           0 :         MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
    2839             :                               JSPROP_PERMANENT |
    2840             :                               JSPROP_READONLY |
    2841             :                               JSPROP_IGNORE_ENUMERATE |
    2842             :                               JSPROP_IGNORE_PERMANENT |
    2843             :                               JSPROP_IGNORE_READONLY)) == 0);
    2844           0 :         object().set(nullptr);
    2845           0 :         setAttributes(attrs);
    2846           0 :         setGetter(nullptr);
    2847           0 :         setSetter(nullptr);
    2848           0 :         value().set(v);
    2849           0 :     }
    2850             : 
    2851      163282 :     JS::MutableHandleObject object() {
    2852      163282 :         return JS::MutableHandleObject::fromMarkedLocation(&desc().obj);
    2853             :     }
    2854      237565 :     unsigned& attributesRef() { return desc().attrs; }
    2855           0 :     JSGetterOp& getter() { return desc().getter; }
    2856           0 :     JSSetterOp& setter() { return desc().setter; }
    2857      141327 :     JS::MutableHandleValue value() {
    2858      141327 :         return JS::MutableHandleValue::fromMarkedLocation(&desc().value);
    2859             :     }
    2860         795 :     void setValue(JS::HandleValue v) {
    2861         795 :         MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
    2862         795 :         attributesRef() &= ~JSPROP_IGNORE_VALUE;
    2863         795 :         value().set(v);
    2864         795 :     }
    2865             : 
    2866           5 :     void setConfigurable(bool configurable) {
    2867           5 :         setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
    2868             :                       (configurable ? 0 : JSPROP_PERMANENT));
    2869           5 :     }
    2870         848 :     void setEnumerable(bool enumerable) {
    2871         848 :         setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
    2872             :                       (enumerable ? JSPROP_ENUMERATE : 0));
    2873         848 :     }
    2874         622 :     void setWritable(bool writable) {
    2875         622 :         MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
    2876         622 :         setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
    2877             :                       (writable ? 0 : JSPROP_READONLY));
    2878         622 :     }
    2879      138347 :     void setAttributes(unsigned attrs) { desc().attrs = attrs; }
    2880             : 
    2881      133376 :     void setGetter(JSGetterOp op) {
    2882      133376 :         MOZ_ASSERT(op != JS_PropertyStub);
    2883      133376 :         desc().getter = op;
    2884      133375 :     }
    2885      133439 :     void setSetter(JSSetterOp op) {
    2886      133439 :         MOZ_ASSERT(op != JS_StrictPropertyStub);
    2887      133439 :         desc().setter = op;
    2888      133438 :     }
    2889        2318 :     void setGetterObject(JSObject* obj) {
    2890        2318 :         desc().getter = reinterpret_cast<JSGetterOp>(obj);
    2891        2318 :         desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
    2892        2318 :         desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
    2893        2318 :     }
    2894        9850 :     void setSetterObject(JSObject* obj) {
    2895        9850 :         desc().setter = reinterpret_cast<JSSetterOp>(obj);
    2896        9850 :         desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
    2897        9850 :         desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
    2898        9850 :     }
    2899             : 
    2900        1486 :     JS::MutableHandleObject getterObject() {
    2901        1486 :         MOZ_ASSERT(this->hasGetterObject());
    2902        1486 :         return JS::MutableHandleObject::fromMarkedLocation(
    2903        2972 :                 reinterpret_cast<JSObject**>(&desc().getter));
    2904             :     }
    2905          53 :     JS::MutableHandleObject setterObject() {
    2906          53 :         MOZ_ASSERT(this->hasSetterObject());
    2907          53 :         return JS::MutableHandleObject::fromMarkedLocation(
    2908         106 :                 reinterpret_cast<JSObject**>(&desc().setter));
    2909             :     }
    2910             : };
    2911             : 
    2912             : } // namespace js
    2913             : 
    2914             : namespace JS {
    2915             : 
    2916             : extern JS_PUBLIC_API(bool)
    2917             : ObjectToCompletePropertyDescriptor(JSContext* cx,
    2918             :                                    JS::HandleObject obj,
    2919             :                                    JS::HandleValue descriptor,
    2920             :                                    JS::MutableHandle<PropertyDescriptor> desc);
    2921             : 
    2922             : /*
    2923             :  * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc).
    2924             :  *
    2925             :  * If desc.object() is null, then vp is set to undefined.
    2926             :  */
    2927             : extern JS_PUBLIC_API(bool)
    2928             : FromPropertyDescriptor(JSContext* cx,
    2929             :                        JS::Handle<JS::PropertyDescriptor> desc,
    2930             :                        JS::MutableHandleValue vp);
    2931             : 
    2932             : } // namespace JS
    2933             : 
    2934             : 
    2935             : /*** Standard internal methods ********************************************************************
    2936             :  *
    2937             :  * The functions below are the fundamental operations on objects.
    2938             :  *
    2939             :  * ES6 specifies 14 internal methods that define how objects behave.  The
    2940             :  * standard is actually quite good on this topic, though you may have to read
    2941             :  * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
    2942             :  *
    2943             :  * When 'obj' is an ordinary object, these functions have boring standard
    2944             :  * behavior as specified by ES6 section 9.1; see the section about internal
    2945             :  * methods in js/src/vm/NativeObject.h.
    2946             :  *
    2947             :  * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
    2948             :  * any one of the functions below could do just about anything. See
    2949             :  * js/public/Proxy.h.
    2950             :  */
    2951             : 
    2952             : /**
    2953             :  * Get the prototype of obj, storing it in result.
    2954             :  *
    2955             :  * Implements: ES6 [[GetPrototypeOf]] internal method.
    2956             :  */
    2957             : extern JS_PUBLIC_API(bool)
    2958             : JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result);
    2959             : 
    2960             : /**
    2961             :  * If |obj| (underneath any functionally-transparent wrapper proxies) has as
    2962             :  * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
    2963             :  * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
    2964             :  * in |result|.  Otherwise set |*isOrdinary = false|.  In case of error, both
    2965             :  * outparams have unspecified value.
    2966             :  */
    2967             : extern JS_PUBLIC_API(bool)
    2968             : JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
    2969             :                           JS::MutableHandleObject result);
    2970             : 
    2971             : /**
    2972             :  * Change the prototype of obj.
    2973             :  *
    2974             :  * Implements: ES6 [[SetPrototypeOf]] internal method.
    2975             :  *
    2976             :  * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
    2977             :  * JS_SetPrototype throws a TypeError and returns false.
    2978             :  *
    2979             :  * Performance warning: JS_SetPrototype is very bad for performance. It may
    2980             :  * cause compiled jit-code to be invalidated. It also causes not only obj but
    2981             :  * all other objects in the same "group" as obj to be permanently deoptimized.
    2982             :  * It's better to create the object with the right prototype from the start.
    2983             :  */
    2984             : extern JS_PUBLIC_API(bool)
    2985             : JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
    2986             : 
    2987             : /**
    2988             :  * Determine whether obj is extensible. Extensible objects can have new
    2989             :  * properties defined on them. Inextensible objects can't, and their
    2990             :  * [[Prototype]] slot is fixed as well.
    2991             :  *
    2992             :  * Implements: ES6 [[IsExtensible]] internal method.
    2993             :  */
    2994             : extern JS_PUBLIC_API(bool)
    2995             : JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible);
    2996             : 
    2997             : /**
    2998             :  * Attempt to make |obj| non-extensible.
    2999             :  *
    3000             :  * Not all failures are treated as errors. See the comment on
    3001             :  * JS::ObjectOpResult in js/public/Class.h.
    3002             :  *
    3003             :  * Implements: ES6 [[PreventExtensions]] internal method.
    3004             :  */
    3005             : extern JS_PUBLIC_API(bool)
    3006             : JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
    3007             : 
    3008             : /**
    3009             :  * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
    3010             :  * to modify it will fail.  If an error occurs during the attempt, return false
    3011             :  * (with a pending exception set, depending upon the nature of the error).  If
    3012             :  * no error occurs, return true with |*succeeded| set to indicate whether the
    3013             :  * attempt successfully made the [[Prototype]] immutable.
    3014             :  *
    3015             :  * This is a nonstandard internal method.
    3016             :  */
    3017             : extern JS_PUBLIC_API(bool)
    3018             : JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded);
    3019             : 
    3020             : /**
    3021             :  * Get a description of one of obj's own properties. If no such property exists
    3022             :  * on obj, return true with desc.object() set to null.
    3023             :  *
    3024             :  * Implements: ES6 [[GetOwnProperty]] internal method.
    3025             :  */
    3026             : extern JS_PUBLIC_API(bool)
    3027             : JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3028             :                                 JS::MutableHandle<JS::PropertyDescriptor> desc);
    3029             : 
    3030             : extern JS_PUBLIC_API(bool)
    3031             : JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
    3032             :                             JS::MutableHandle<JS::PropertyDescriptor> desc);
    3033             : 
    3034             : extern JS_PUBLIC_API(bool)
    3035             : JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
    3036             :                               JS::MutableHandle<JS::PropertyDescriptor> desc);
    3037             : 
    3038             : /**
    3039             :  * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
    3040             :  * if no own property is found directly on obj. The object on which the
    3041             :  * property is found is returned in desc.object(). If the property is not found
    3042             :  * on the prototype chain, this returns true with desc.object() set to null.
    3043             :  */
    3044             : extern JS_PUBLIC_API(bool)
    3045             : JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3046             :                              JS::MutableHandle<JS::PropertyDescriptor> desc);
    3047             : 
    3048             : extern JS_PUBLIC_API(bool)
    3049             : JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
    3050             :                          JS::MutableHandle<JS::PropertyDescriptor> desc);
    3051             : 
    3052             : /**
    3053             :  * Define a property on obj.
    3054             :  *
    3055             :  * This function uses JS::ObjectOpResult to indicate conditions that ES6
    3056             :  * specifies as non-error failures. This is inconvenient at best, so use this
    3057             :  * function only if you are implementing a proxy handler's defineProperty()
    3058             :  * method. For all other purposes, use one of the many DefineProperty functions
    3059             :  * below that throw an exception in all failure cases.
    3060             :  *
    3061             :  * Implements: ES6 [[DefineOwnProperty]] internal method.
    3062             :  */
    3063             : extern JS_PUBLIC_API(bool)
    3064             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3065             :                       JS::Handle<JS::PropertyDescriptor> desc,
    3066             :                       JS::ObjectOpResult& result);
    3067             : 
    3068             : /**
    3069             :  * Define a property on obj, throwing a TypeError if the attempt fails.
    3070             :  * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
    3071             :  */
    3072             : extern JS_PUBLIC_API(bool)
    3073             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3074             :                       JS::Handle<JS::PropertyDescriptor> desc);
    3075             : 
    3076             : extern JS_PUBLIC_API(bool)
    3077             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
    3078             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3079             : 
    3080             : extern JS_PUBLIC_API(bool)
    3081             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
    3082             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3083             : 
    3084             : extern JS_PUBLIC_API(bool)
    3085             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
    3086             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3087             : 
    3088             : extern JS_PUBLIC_API(bool)
    3089             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
    3090             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3091             : 
    3092             : extern JS_PUBLIC_API(bool)
    3093             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
    3094             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3095             : 
    3096             : extern JS_PUBLIC_API(bool)
    3097             : JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value,
    3098             :                       unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3099             : 
    3100             : extern JS_PUBLIC_API(bool)
    3101             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value,
    3102             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3103             : 
    3104             : extern JS_PUBLIC_API(bool)
    3105             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
    3106             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3107             : 
    3108             : extern JS_PUBLIC_API(bool)
    3109             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value,
    3110             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3111             : 
    3112             : extern JS_PUBLIC_API(bool)
    3113             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value,
    3114             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3115             : 
    3116             : extern JS_PUBLIC_API(bool)
    3117             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value,
    3118             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3119             : 
    3120             : extern JS_PUBLIC_API(bool)
    3121             : JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value,
    3122             :                   unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3123             : 
    3124             : extern JS_PUBLIC_API(bool)
    3125             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3126             :                     JS::Handle<JS::PropertyDescriptor> desc,
    3127             :                     JS::ObjectOpResult& result);
    3128             : 
    3129             : extern JS_PUBLIC_API(bool)
    3130             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3131             :                     JS::Handle<JS::PropertyDescriptor> desc);
    3132             : 
    3133             : extern JS_PUBLIC_API(bool)
    3134             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3135             :                     JS::HandleValue value, unsigned attrs,
    3136             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3137             : 
    3138             : extern JS_PUBLIC_API(bool)
    3139             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3140             :                     JS::HandleObject value, unsigned attrs,
    3141             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3142             : 
    3143             : extern JS_PUBLIC_API(bool)
    3144             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3145             :                     JS::HandleString value, unsigned attrs,
    3146             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3147             : 
    3148             : extern JS_PUBLIC_API(bool)
    3149             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3150             :                     int32_t value, unsigned attrs,
    3151             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3152             : 
    3153             : extern JS_PUBLIC_API(bool)
    3154             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3155             :                     uint32_t value, unsigned attrs,
    3156             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3157             : 
    3158             : extern JS_PUBLIC_API(bool)
    3159             : JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3160             :                     double value, unsigned attrs,
    3161             :                     JSNative getter = nullptr, JSNative setter = nullptr);
    3162             : 
    3163             : extern JS_PUBLIC_API(bool)
    3164             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
    3165             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3166             : 
    3167             : extern JS_PUBLIC_API(bool)
    3168             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,
    3169             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3170             : 
    3171             : extern JS_PUBLIC_API(bool)
    3172             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value,
    3173             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3174             : 
    3175             : extern JS_PUBLIC_API(bool)
    3176             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value,
    3177             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3178             : 
    3179             : extern JS_PUBLIC_API(bool)
    3180             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value,
    3181             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3182             : 
    3183             : extern JS_PUBLIC_API(bool)
    3184             : JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value,
    3185             :                  unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
    3186             : 
    3187             : /**
    3188             :  * Compute the expression `id in obj`.
    3189             :  *
    3190             :  * If obj has an own or inherited property obj[id], set *foundp = true and
    3191             :  * return true. If not, set *foundp = false and return true. On error, return
    3192             :  * false with an exception pending.
    3193             :  *
    3194             :  * Implements: ES6 [[Has]] internal method.
    3195             :  */
    3196             : extern JS_PUBLIC_API(bool)
    3197             : JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
    3198             : 
    3199             : extern JS_PUBLIC_API(bool)
    3200             : JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
    3201             : 
    3202             : extern JS_PUBLIC_API(bool)
    3203             : JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3204             :                  bool* vp);
    3205             : 
    3206             : extern JS_PUBLIC_API(bool)
    3207             : JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
    3208             : 
    3209             : /**
    3210             :  * Determine whether obj has an own property with the key `id`.
    3211             :  *
    3212             :  * Implements: ES6 7.3.11 HasOwnProperty(O, P).
    3213             :  */
    3214             : extern JS_PUBLIC_API(bool)
    3215             : JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
    3216             : 
    3217             : extern JS_PUBLIC_API(bool)
    3218             : JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
    3219             : 
    3220             : /**
    3221             :  * Get the value of the property `obj[id]`, or undefined if no such property
    3222             :  * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
    3223             :  *
    3224             :  * Most callers don't need the `receiver` argument. Consider using
    3225             :  * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
    3226             :  * method, it's often correct to call this function and pass the receiver
    3227             :  * through.)
    3228             :  *
    3229             :  * Implements: ES6 [[Get]] internal method.
    3230             :  */
    3231             : extern JS_PUBLIC_API(bool)
    3232             : JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3233             :                         JS::HandleValue receiver, JS::MutableHandleValue vp);
    3234             : 
    3235             : extern JS_PUBLIC_API(bool)
    3236             : JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index,
    3237             :                        JS::HandleObject receiver, JS::MutableHandleValue vp);
    3238             : 
    3239             : /**
    3240             :  * Get the value of the property `obj[id]`, or undefined if no such property
    3241             :  * exists. The result is stored in vp.
    3242             :  *
    3243             :  * Implements: ES6 7.3.1 Get(O, P).
    3244             :  */
    3245             : extern JS_PUBLIC_API(bool)
    3246             : JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3247             :                    JS::MutableHandleValue vp);
    3248             : 
    3249             : extern JS_PUBLIC_API(bool)
    3250             : JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
    3251             : 
    3252             : extern JS_PUBLIC_API(bool)
    3253             : JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3254             :                  JS::MutableHandleValue vp);
    3255             : 
    3256             : extern JS_PUBLIC_API(bool)
    3257             : JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
    3258             : 
    3259             : /**
    3260             :  * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
    3261             :  *
    3262             :  * This function has a `receiver` argument that most callers don't need.
    3263             :  * Consider using JS_SetProperty instead.
    3264             :  *
    3265             :  * Implements: ES6 [[Set]] internal method.
    3266             :  */
    3267             : extern JS_PUBLIC_API(bool)
    3268             : JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
    3269             :                         JS::HandleValue receiver, JS::ObjectOpResult& result);
    3270             : 
    3271             : /**
    3272             :  * Perform the assignment `obj[id] = v`.
    3273             :  *
    3274             :  * This function performs non-strict assignment, so if the property is
    3275             :  * read-only, nothing happens and no error is thrown.
    3276             :  */
    3277             : extern JS_PUBLIC_API(bool)
    3278             : JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
    3279             : 
    3280             : extern JS_PUBLIC_API(bool)
    3281             : JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v);
    3282             : 
    3283             : extern JS_PUBLIC_API(bool)
    3284             : JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3285             :                  JS::HandleValue v);
    3286             : 
    3287             : extern JS_PUBLIC_API(bool)
    3288             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
    3289             : 
    3290             : extern JS_PUBLIC_API(bool)
    3291             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
    3292             : 
    3293             : extern JS_PUBLIC_API(bool)
    3294             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
    3295             : 
    3296             : extern JS_PUBLIC_API(bool)
    3297             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v);
    3298             : 
    3299             : extern JS_PUBLIC_API(bool)
    3300             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v);
    3301             : 
    3302             : extern JS_PUBLIC_API(bool)
    3303             : JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v);
    3304             : 
    3305             : /**
    3306             :  * Delete a property. This is the C++ equivalent of
    3307             :  * `result = Reflect.deleteProperty(obj, id)`.
    3308             :  *
    3309             :  * This function has a `result` out parameter that most callers don't need.
    3310             :  * Unless you can pass through an ObjectOpResult provided by your caller, it's
    3311             :  * probably best to use the JS_DeletePropertyById signature with just 3
    3312             :  * arguments.
    3313             :  *
    3314             :  * Implements: ES6 [[Delete]] internal method.
    3315             :  */
    3316             : extern JS_PUBLIC_API(bool)
    3317             : JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3318             :                       JS::ObjectOpResult& result);
    3319             : 
    3320             : extern JS_PUBLIC_API(bool)
    3321             : JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name,
    3322             :                   JS::ObjectOpResult& result);
    3323             : 
    3324             : extern JS_PUBLIC_API(bool)
    3325             : JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
    3326             :                     JS::ObjectOpResult& result);
    3327             : 
    3328             : extern JS_PUBLIC_API(bool)
    3329             : JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result);
    3330             : 
    3331             : /**
    3332             :  * Delete a property, ignoring strict failures. This is the C++ equivalent of
    3333             :  * the JS `delete obj[id]` in non-strict mode code.
    3334             :  */
    3335             : extern JS_PUBLIC_API(bool)
    3336             : JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id);
    3337             : 
    3338             : extern JS_PUBLIC_API(bool)
    3339             : JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name);
    3340             : 
    3341             : extern JS_PUBLIC_API(bool)
    3342             : JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index);
    3343             : 
    3344             : /**
    3345             :  * Get an array of the non-symbol enumerable properties of obj.
    3346             :  * This function is roughly equivalent to:
    3347             :  *
    3348             :  *     var result = [];
    3349             :  *     for (key in obj)
    3350             :  *         result.push(key);
    3351             :  *     return result;
    3352             :  *
    3353             :  * This is the closest thing we currently have to the ES6 [[Enumerate]]
    3354             :  * internal method.
    3355             :  *
    3356             :  * The array of ids returned by JS_Enumerate must be rooted to protect its
    3357             :  * contents from garbage collection. Use JS::Rooted<JS::IdVector>.
    3358             :  */
    3359             : extern JS_PUBLIC_API(bool)
    3360             : JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle<JS::IdVector> props);
    3361             : 
    3362             : /*
    3363             :  * API for determining callability and constructability. [[Call]] and
    3364             :  * [[Construct]] are internal methods that aren't present on all objects, so it
    3365             :  * is useful to ask if they are there or not. The standard itself asks these
    3366             :  * questions routinely.
    3367             :  */
    3368             : namespace JS {
    3369             : 
    3370             : /**
    3371             :  * Return true if the given object is callable. In ES6 terms, an object is
    3372             :  * callable if it has a [[Call]] internal method.
    3373             :  *
    3374             :  * Implements: ES6 7.2.3 IsCallable(argument).
    3375             :  *
    3376             :  * Functions are callable. A scripted proxy or wrapper is callable if its
    3377             :  * target is callable. Most other objects aren't callable.
    3378             :  */
    3379             : extern JS_PUBLIC_API(bool)
    3380             : IsCallable(JSObject* obj);
    3381             : 
    3382             : /**
    3383             :  * Return true if the given object is a constructor. In ES6 terms, an object is
    3384             :  * a constructor if it has a [[Construct]] internal method. The expression
    3385             :  * `new obj()` throws a TypeError if obj is not a constructor.
    3386             :  *
    3387             :  * Implements: ES6 7.2.4 IsConstructor(argument).
    3388             :  *
    3389             :  * JS functions and classes are constructors. Arrow functions and most builtin
    3390             :  * functions are not. A scripted proxy or wrapper is a constructor if its
    3391             :  * target is a constructor.
    3392             :  */
    3393             : extern JS_PUBLIC_API(bool)
    3394             : IsConstructor(JSObject* obj);
    3395             : 
    3396             : } /* namespace JS */
    3397             : 
    3398             : /**
    3399             :  * Call a function, passing a this-value and arguments. This is the C++
    3400             :  * equivalent of `rval = Reflect.apply(fun, obj, args)`.
    3401             :  *
    3402             :  * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
    3403             :  * Use this function to invoke the [[Call]] internal method.
    3404             :  */
    3405             : extern JS_PUBLIC_API(bool)
    3406             : JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval,
    3407             :                      const JS::HandleValueArray& args, JS::MutableHandleValue rval);
    3408             : 
    3409             : extern JS_PUBLIC_API(bool)
    3410             : JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun,
    3411             :                 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
    3412             : 
    3413             : /**
    3414             :  * Perform the method call `rval = obj[name](args)`.
    3415             :  */
    3416             : extern JS_PUBLIC_API(bool)
    3417             : JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name,
    3418             :                     const JS::HandleValueArray& args, JS::MutableHandleValue rval);
    3419             : 
    3420             : namespace JS {
    3421             : 
    3422             : static inline bool
    3423             : Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun,
    3424             :      const JS::HandleValueArray& args, MutableHandleValue rval)
    3425             : {
    3426             :     return !!JS_CallFunction(cx, thisObj, fun, args, rval);
    3427             : }
    3428             : 
    3429             : static inline bool
    3430          48 : Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
    3431             :      MutableHandleValue rval)
    3432             : {
    3433          48 :     return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
    3434             : }
    3435             : 
    3436             : static inline bool
    3437             : Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args,
    3438             :      MutableHandleValue rval)
    3439             : {
    3440             :     return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
    3441             : }
    3442             : 
    3443             : extern JS_PUBLIC_API(bool)
    3444             : Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
    3445             :      MutableHandleValue rval);
    3446             : 
    3447             : static inline bool
    3448         180 : Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
    3449             :      MutableHandleValue rval)
    3450             : {
    3451         180 :     MOZ_ASSERT(funObj);
    3452         360 :     JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
    3453         360 :     return Call(cx, thisv, fun, args, rval);
    3454             : }
    3455             : 
    3456             : /**
    3457             :  * Invoke a constructor. This is the C++ equivalent of
    3458             :  * `rval = Reflect.construct(fun, args, newTarget)`.
    3459             :  *
    3460             :  * JS::Construct() takes a `newTarget` argument that most callers don't need.
    3461             :  * Consider using the four-argument Construct signature instead. (But if you're
    3462             :  * implementing a subclass or a proxy handler's construct() method, this is the
    3463             :  * right function to call.)
    3464             :  *
    3465             :  * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
    3466             :  * Use this function to invoke the [[Construct]] internal method.
    3467             :  */
    3468             : extern JS_PUBLIC_API(bool)
    3469             : Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget,
    3470             :           const JS::HandleValueArray &args, MutableHandleObject objp);
    3471             : 
    3472             : /**
    3473             :  * Invoke a constructor. This is the C++ equivalent of
    3474             :  * `rval = new fun(...args)`.
    3475             :  *
    3476             :  * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
    3477             :  * newTarget is omitted.
    3478             :  */
    3479             : extern JS_PUBLIC_API(bool)
    3480             : Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args,
    3481             :           MutableHandleObject objp);
    3482             : 
    3483             : } /* namespace JS */
    3484             : 
    3485             : /**
    3486             :  * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
    3487             :  * the new object, or null on error.
    3488             :  */
    3489             : extern JS_PUBLIC_API(JSObject*)
    3490             : JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
    3491             : 
    3492             : 
    3493             : /*** Other property-defining functions ***********************************************************/
    3494             : 
    3495             : extern JS_PUBLIC_API(JSObject*)
    3496             : JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name,
    3497             :                 const JSClass* clasp = nullptr, unsigned attrs = 0);
    3498             : 
    3499             : extern JS_PUBLIC_API(bool)
    3500             : JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds);
    3501             : 
    3502             : extern JS_PUBLIC_API(bool)
    3503             : JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis);
    3504             : 
    3505             : extern JS_PUBLIC_API(bool)
    3506             : JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps);
    3507             : 
    3508             : 
    3509             : /* * */
    3510             : 
    3511             : extern JS_PUBLIC_API(bool)
    3512             : JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
    3513             :                              bool* foundp);
    3514             : 
    3515             : extern JS_PUBLIC_API(bool)
    3516             : JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name,
    3517             :                          bool* foundp);
    3518             : 
    3519             : extern JS_PUBLIC_API(bool)
    3520             : JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name,
    3521             :                            size_t namelen, bool* foundp);
    3522             : 
    3523             : extern JS_PUBLIC_API(bool)
    3524             : JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
    3525             : 
    3526             : extern JS_PUBLIC_API(JSObject*)
    3527             : JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents);
    3528             : 
    3529             : extern JS_PUBLIC_API(JSObject*)
    3530             : JS_NewArrayObject(JSContext* cx, size_t length);
    3531             : 
    3532             : /**
    3533             :  * Returns true and sets |*isArray| indicating whether |value| is an Array
    3534             :  * object or a wrapper around one, otherwise returns false on failure.
    3535             :  *
    3536             :  * This method returns true with |*isArray == false| when passed a proxy whose
    3537             :  * target is an Array, or when passed a revoked proxy.
    3538             :  */
    3539             : extern JS_PUBLIC_API(bool)
    3540             : JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray);
    3541             : 
    3542             : /**
    3543             :  * Returns true and sets |*isArray| indicating whether |obj| is an Array object
    3544             :  * or a wrapper around one, otherwise returns false on failure.
    3545             :  *
    3546             :  * This method returns true with |*isArray == false| when passed a proxy whose
    3547             :  * target is an Array, or when passed a revoked proxy.
    3548             :  */
    3549             : extern JS_PUBLIC_API(bool)
    3550             : JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray);
    3551             : 
    3552             : extern JS_PUBLIC_API(bool)
    3553             : JS_GetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t* lengthp);
    3554             : 
    3555             : extern JS_PUBLIC_API(bool)
    3556             : JS_SetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t length);
    3557             : 
    3558             : namespace JS {
    3559             : 
    3560             : /**
    3561             :  * Returns true and sets |*isMap| indicating whether |obj| is an Map object
    3562             :  * or a wrapper around one, otherwise returns false on failure.
    3563             :  *
    3564             :  * This method returns true with |*isMap == false| when passed a proxy whose
    3565             :  * target is an Map, or when passed a revoked proxy.
    3566             :  */
    3567             : extern JS_PUBLIC_API(bool)
    3568             : IsMapObject(JSContext* cx, JS::HandleObject obj, bool* isMap);
    3569             : 
    3570             : /**
    3571             :  * Returns true and sets |*isSet| indicating whether |obj| is an Set object
    3572             :  * or a wrapper around one, otherwise returns false on failure.
    3573             :  *
    3574             :  * This method returns true with |*isSet == false| when passed a proxy whose
    3575             :  * target is an Set, or when passed a revoked proxy.
    3576             :  */
    3577             : extern JS_PUBLIC_API(bool)
    3578             : IsSetObject(JSContext* cx, JS::HandleObject obj, bool* isSet);
    3579             : 
    3580             : } /* namespace JS */
    3581             : 
    3582             : /**
    3583             :  * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
    3584             :  * done for all slots, regardless of the associated property descriptor.
    3585             :  */
    3586             : JS_PUBLIC_API(void)
    3587             : JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg);
    3588             : 
    3589             : /**
    3590             :  * Create a new array buffer with the given contents. It must be legal to pass
    3591             :  * these contents to free(). On success, the ownership is transferred to the
    3592             :  * new array buffer.
    3593             :  */
    3594             : extern JS_PUBLIC_API(JSObject*)
    3595             : JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
    3596             : 
    3597             : /**
    3598             :  * Create a new array buffer with the given contents.  The array buffer does not take ownership of
    3599             :  * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of.
    3600             :  */
    3601             : extern JS_PUBLIC_API(JSObject*)
    3602             : JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents);
    3603             : 
    3604             : /**
    3605             :  * Steal the contents of the given array buffer. The array buffer has its
    3606             :  * length set to 0 and its contents array cleared. The caller takes ownership
    3607             :  * of the return value and must free it or transfer ownership via
    3608             :  * JS_NewArrayBufferWithContents when done using it.
    3609             :  */
    3610             : extern JS_PUBLIC_API(void*)
    3611             : JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj);
    3612             : 
    3613             : /**
    3614             :  * Returns a pointer to the ArrayBuffer |obj|'s data.  |obj| and its views will store and expose
    3615             :  * the data in the returned pointer: assigning into the returned pointer will affect values exposed
    3616             :  * by views of |obj| and vice versa.
    3617             :  *
    3618             :  * The caller must ultimately deallocate the returned pointer to avoid leaking.  The memory is
    3619             :  * *not* garbage-collected with |obj|.  These steps must be followed to deallocate:
    3620             :  *
    3621             :  * 1. The ArrayBuffer |obj| must be detached using JS_DetachArrayBuffer.
    3622             :  * 2. The returned pointer must be freed using JS_free.
    3623             :  *
    3624             :  * To perform step 1, callers *must* hold a reference to |obj| until they finish using the returned
    3625             :  * pointer.  They *must not* attempt to let |obj| be GC'd, then JS_free the pointer.
    3626             :  *
    3627             :  * If |obj| isn't an ArrayBuffer, this function returns null and reports an error.
    3628             :  */
    3629             : extern JS_PUBLIC_API(void*)
    3630             : JS_ExternalizeArrayBufferContents(JSContext* cx, JS::HandleObject obj);
    3631             : 
    3632             : /**
    3633             :  * Create a new mapped array buffer with the given memory mapped contents. It
    3634             :  * must be legal to free the contents pointer by unmapping it. On success,
    3635             :  * ownership is transferred to the new mapped array buffer.
    3636             :  */
    3637             : extern JS_PUBLIC_API(JSObject*)
    3638             : JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
    3639             : 
    3640             : /**
    3641             :  * Create memory mapped array buffer contents.
    3642             :  * Caller must take care of closing fd after calling this function.
    3643             :  */
    3644             : extern JS_PUBLIC_API(void*)
    3645             : JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
    3646             : 
    3647             : /**
    3648             :  * Release the allocated resource of mapped array buffer contents before the
    3649             :  * object is created.
    3650             :  * If a new object has been created by JS_NewMappedArrayBufferWithContents()
    3651             :  * with this content, then JS_DetachArrayBuffer() should be used instead to
    3652             :  * release the resource used by the object.
    3653             :  */
    3654             : extern JS_PUBLIC_API(void)
    3655             : JS_ReleaseMappedArrayBufferContents(void* contents, size_t length);
    3656             : 
    3657             : extern JS_PUBLIC_API(JS::Value)
    3658             : JS_GetReservedSlot(JSObject* obj, uint32_t index);
    3659             : 
    3660             : extern JS_PUBLIC_API(void)
    3661             : JS_SetReservedSlot(JSObject* obj, uint32_t index, const JS::Value& v);
    3662             : 
    3663             : 
    3664             : /************************************************************************/
    3665             : 
    3666             : /*
    3667             :  * Functions and scripts.
    3668             :  */
    3669             : extern JS_PUBLIC_API(JSFunction*)
    3670             : JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
    3671             :                const char* name);
    3672             : 
    3673             : namespace JS {
    3674             : 
    3675             : extern JS_PUBLIC_API(JSFunction*)
    3676             : GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id,
    3677             :                       unsigned nargs);
    3678             : 
    3679             : /**
    3680             :  * Create a new function based on the given JSFunctionSpec, *fs.
    3681             :  * id is the result of a successful call to
    3682             :  * `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
    3683             :  *
    3684             :  * Unlike JS_DefineFunctions, this does not treat fs as an array.
    3685             :  * *fs must not be JS_FS_END.
    3686             :  */
    3687             : extern JS_PUBLIC_API(JSFunction*)
    3688             : NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id);
    3689             : 
    3690             : } /* namespace JS */
    3691             : 
    3692             : extern JS_PUBLIC_API(JSObject*)
    3693             : JS_GetFunctionObject(JSFunction* fun);
    3694             : 
    3695             : /**
    3696             :  * Return the function's identifier as a JSString, or null if fun is unnamed.
    3697             :  * The returned string lives as long as fun, so you don't need to root a saved
    3698             :  * reference to it if fun is well-connected or rooted, and provided you bound
    3699             :  * the use of the saved reference by fun's lifetime.
    3700             :  */
    3701             : extern JS_PUBLIC_API(JSString*)
    3702             : JS_GetFunctionId(JSFunction* fun);
    3703             : 
    3704             : /**
    3705             :  * Return a function's display name. This is the defined name if one was given
    3706             :  * where the function was defined, or it could be an inferred name by the JS
    3707             :  * engine in the case that the function was defined to be anonymous. This can
    3708             :  * still return nullptr if a useful display name could not be inferred. The
    3709             :  * same restrictions on rooting as those in JS_GetFunctionId apply.
    3710             :  */
    3711             : extern JS_PUBLIC_API(JSString*)
    3712             : JS_GetFunctionDisplayId(JSFunction* fun);
    3713             : 
    3714             : /*
    3715             :  * Return the arity (length) of fun.
    3716             :  */
    3717             : extern JS_PUBLIC_API(uint16_t)
    3718             : JS_GetFunctionArity(JSFunction* fun);
    3719             : 
    3720             : /**
    3721             :  * Infallible predicate to test whether obj is a function object (faster than
    3722             :  * comparing obj's class name to "Function", but equivalent unless someone has
    3723             :  * overwritten the "Function" identifier with a different constructor and then
    3724             :  * created instances using that constructor that might be passed in as obj).
    3725             :  */
    3726             : extern JS_PUBLIC_API(bool)
    3727             : JS_ObjectIsFunction(JSContext* cx, JSObject* obj);
    3728             : 
    3729             : extern JS_PUBLIC_API(bool)
    3730             : JS_IsNativeFunction(JSObject* funobj, JSNative call);
    3731             : 
    3732             : /** Return whether the given function is a valid constructor. */
    3733             : extern JS_PUBLIC_API(bool)
    3734             : JS_IsConstructor(JSFunction* fun);
    3735             : 
    3736             : extern JS_PUBLIC_API(bool)
    3737             : JS_DefineFunctions(JSContext* cx, JS::Handle<JSObject*> obj, const JSFunctionSpec* fs);
    3738             : 
    3739             : extern JS_PUBLIC_API(JSFunction*)
    3740             : JS_DefineFunction(JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
    3741             :                   unsigned nargs, unsigned attrs);
    3742             : 
    3743             : extern JS_PUBLIC_API(JSFunction*)
    3744             : JS_DefineUCFunction(JSContext* cx, JS::Handle<JSObject*> obj,
    3745             :                     const char16_t* name, size_t namelen, JSNative call,
    3746             :                     unsigned nargs, unsigned attrs);
    3747             : 
    3748             : extern JS_PUBLIC_API(JSFunction*)
    3749             : JS_DefineFunctionById(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
    3750             :                       unsigned nargs, unsigned attrs);
    3751             : 
    3752             : extern JS_PUBLIC_API(bool)
    3753             : JS_IsFunctionBound(JSFunction* fun);
    3754             : 
    3755             : extern JS_PUBLIC_API(JSObject*)
    3756             : JS_GetBoundFunctionTarget(JSFunction* fun);
    3757             : 
    3758             : namespace JS {
    3759             : 
    3760             : /**
    3761             :  * Clone a top-level function into cx's global. This function will dynamically
    3762             :  * fail if funobj was lexically nested inside some other function.
    3763             :  */
    3764             : extern JS_PUBLIC_API(JSObject*)
    3765             : CloneFunctionObject(JSContext* cx, HandleObject funobj);
    3766             : 
    3767             : /**
    3768             :  * As above, but providing an explicit scope chain.  scopeChain must not include
    3769             :  * the global object on it; that's implicit.  It needs to contain the other
    3770             :  * objects that should end up on the clone's scope chain.
    3771             :  */
    3772             : extern JS_PUBLIC_API(JSObject*)
    3773             : CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain);
    3774             : 
    3775             : } // namespace JS
    3776             : 
    3777             : /**
    3778             :  * Given a buffer, return false if the buffer might become a valid
    3779             :  * javascript statement with the addition of more lines.  Otherwise return
    3780             :  * true.  The intent is to support interactive compilation - accumulate
    3781             :  * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
    3782             :  * the compiler.
    3783             :  */
    3784             : extern JS_PUBLIC_API(bool)
    3785             : JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
    3786             :                           size_t length);
    3787             : 
    3788             : /**
    3789             :  * |script| will always be set. On failure, it will be set to nullptr.
    3790             :  */
    3791             : extern JS_PUBLIC_API(bool)
    3792             : JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
    3793             :                  const JS::CompileOptions& options,
    3794             :                  JS::MutableHandleScript script);
    3795             : 
    3796             : /**
    3797             :  * |script| will always be set. On failure, it will be set to nullptr.
    3798             :  */
    3799             : extern JS_PUBLIC_API(bool)
    3800             : JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length,
    3801             :                    const JS::CompileOptions& options,
    3802             :                    JS::MutableHandleScript script);
    3803             : 
    3804             : extern JS_PUBLIC_API(JSObject*)
    3805             : JS_GetGlobalFromScript(JSScript* script);
    3806             : 
    3807             : extern JS_PUBLIC_API(const char*)
    3808             : JS_GetScriptFilename(JSScript* script);
    3809             : 
    3810             : extern JS_PUBLIC_API(unsigned)
    3811             : JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
    3812             : 
    3813             : extern JS_PUBLIC_API(JSScript*)
    3814             : JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun);
    3815             : 
    3816             : namespace JS {
    3817             : 
    3818             : /* Options for JavaScript compilation. */
    3819             : 
    3820             : /*
    3821             :  * In the most common use case, a CompileOptions instance is allocated on the
    3822             :  * stack, and holds non-owning references to non-POD option values: strings;
    3823             :  * principals; objects; and so on. The code declaring the instance guarantees
    3824             :  * that such option values will outlive the CompileOptions itself: objects are
    3825             :  * otherwise rooted; principals have had their reference counts bumped; strings
    3826             :  * will not be freed until the CompileOptions goes out of scope. In this
    3827             :  * situation, CompileOptions only refers to things others own, so it can be
    3828             :  * lightweight.
    3829             :  *
    3830             :  * In some cases, however, we need to hold compilation options with a
    3831             :  * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
    3832             :  * compilation options where a worker thread can find them, and then return
    3833             :  * immediately. The worker thread will come along at some later point, and use
    3834             :  * the options.
    3835             :  *
    3836             :  * The compiler itself just needs to be able to access a collection of options;
    3837             :  * it doesn't care who owns them, or what's keeping them alive. It does its own
    3838             :  * addrefs/copies/tracing/etc.
    3839             :  *
    3840             :  * Furthermore, in some cases compile options are propagated from one entity to
    3841             :  * another (e.g. from a script to a function defined in that script).  This
    3842             :  * involves copying over some, but not all, of the options.
    3843             :  *
    3844             :  * So, we have a class hierarchy that reflects these four use cases:
    3845             :  *
    3846             :  * - TransitiveCompileOptions is the common base class, representing options
    3847             :  *   that should get propagated from a script to functions defined in that
    3848             :  *   script.  This is never instantiated directly.
    3849             :  *
    3850             :  * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions,
    3851             :  *   representing a full set of compile options.  It can be used by code that
    3852             :  *   simply needs to access options set elsewhere, like the compiler.  This,
    3853             :  *   again, is never instantiated directly.
    3854             :  *
    3855             :  * - The usual CompileOptions class must be stack-allocated, and holds
    3856             :  *   non-owning references to the filename, element, and so on. It's derived
    3857             :  *   from ReadOnlyCompileOptions, so the compiler can use it.
    3858             :  *
    3859             :  * - OwningCompileOptions roots / copies / reference counts of all its values,
    3860             :  *   and unroots / frees / releases them when it is destructed. It too is
    3861             :  *   derived from ReadOnlyCompileOptions, so the compiler accepts it.
    3862             :  */
    3863             : 
    3864             : enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger };
    3865             : 
    3866             : /**
    3867             :  * The common base class for the CompileOptions hierarchy.
    3868             :  *
    3869             :  * Use this in code that needs to propagate compile options from one compilation
    3870             :  * unit to another.
    3871             :  */
    3872             : class JS_FRIEND_API(TransitiveCompileOptions)
    3873             : {
    3874             :   protected:
    3875             :     // The Web Platform allows scripts to be loaded from arbitrary cross-origin
    3876             :     // sources. This allows an attack by which a malicious website loads a
    3877             :     // sensitive file (say, a bank statement) cross-origin (using the user's
    3878             :     // cookies), and sniffs the generated syntax errors (via a window.onerror
    3879             :     // handler) for juicy morsels of its contents.
    3880             :     //
    3881             :     // To counter this attack, HTML5 specifies that script errors should be
    3882             :     // sanitized ("muted") when the script is not same-origin with the global
    3883             :     // for which it is loaded. Callers should set this flag for cross-origin
    3884             :     // scripts, and it will be propagated appropriately to child scripts and
    3885             :     // passed back in JSErrorReports.
    3886             :     bool mutedErrors_;
    3887             :     const char* filename_;
    3888             :     const char* introducerFilename_;
    3889             :     const char16_t* sourceMapURL_;
    3890             : 
    3891             :     // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
    3892             :     // is unusable until that's set to something more specific; the derived
    3893             :     // classes' constructors take care of that, in ways appropriate to their
    3894             :     // purpose.
    3895       25640 :     TransitiveCompileOptions()
    3896       25640 :       : mutedErrors_(false),
    3897             :         filename_(nullptr),
    3898             :         introducerFilename_(nullptr),
    3899             :         sourceMapURL_(nullptr),
    3900             :         version(JSVERSION_UNKNOWN),
    3901             :         versionSet(false),
    3902             :         utf8(false),
    3903             :         selfHostingMode(false),
    3904             :         canLazilyParse(true),
    3905             :         strictOption(false),
    3906             :         extraWarningsOption(false),
    3907             :         forEachStatementOption(false),
    3908             :         werrorOption(false),
    3909             :         asmJSOption(AsmJSOption::Disabled),
    3910             :         throwOnAsmJSValidationFailureOption(false),
    3911             :         forceAsync(false),
    3912             :         sourceIsLazy(false),
    3913             :         allowHTMLComments(true),
    3914             :         isProbablySystemOrAddonCode(false),
    3915             :         introductionType(nullptr),
    3916             :         introductionLineno(0),
    3917             :         introductionOffset(0),
    3918       25640 :         hasIntroductionInfo(false)
    3919       25640 :     { }
    3920             : 
    3921             :     // Set all POD options (those not requiring reference counts, copies,
    3922             :     // rooting, or other hand-holding) to their values in |rhs|.
    3923             :     void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs);
    3924             : 
    3925             :   public:
    3926             :     // Read-only accessors for non-POD options. The proper way to set these
    3927             :     // depends on the derived type.
    3928             :     bool mutedErrors() const { return mutedErrors_; }
    3929        3982 :     const char* filename() const { return filename_; }
    3930        3982 :     const char* introducerFilename() const { return introducerFilename_; }
    3931        3982 :     const char16_t* sourceMapURL() const { return sourceMapURL_; }
    3932             :     virtual JSObject* element() const = 0;
    3933             :     virtual JSString* elementAttributeName() const = 0;
    3934             :     virtual JSScript* introductionScript() const = 0;
    3935             : 
    3936             :     // POD options.
    3937             :     JSVersion version;
    3938             :     bool versionSet;
    3939             :     bool utf8;
    3940             :     bool selfHostingMode;
    3941             :     bool canLazilyParse;
    3942             :     bool strictOption;
    3943             :     bool extraWarningsOption;
    3944             :     bool forEachStatementOption;
    3945             :     bool werrorOption;
    3946             :     AsmJSOption asmJSOption;
    3947             :     bool throwOnAsmJSValidationFailureOption;
    3948             :     bool forceAsync;
    3949             :     bool sourceIsLazy;
    3950             :     bool allowHTMLComments;
    3951             :     bool isProbablySystemOrAddonCode;
    3952             : 
    3953             :     // |introductionType| is a statically allocated C string:
    3954             :     // one of "eval", "Function", or "GeneratorFunction".
    3955             :     const char* introductionType;
    3956             :     unsigned introductionLineno;
    3957             :     uint32_t introductionOffset;
    3958             :     bool hasIntroductionInfo;
    3959             : 
    3960             :   private:
    3961             :     void operator=(const TransitiveCompileOptions&) = delete;
    3962             : };
    3963             : 
    3964             : /**
    3965             :  * The class representing a full set of compile options.
    3966             :  *
    3967             :  * Use this in code that only needs to access compilation options created
    3968             :  * elsewhere, like the compiler. Don't instantiate this class (the constructor
    3969             :  * is protected anyway); instead, create instances only of the derived classes:
    3970             :  * CompileOptions and OwningCompileOptions.
    3971             :  */
    3972             : class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions
    3973             : {
    3974             :     friend class CompileOptions;
    3975             : 
    3976             :   protected:
    3977       25640 :     ReadOnlyCompileOptions()
    3978       25640 :       : TransitiveCompileOptions(),
    3979             :         lineno(1),
    3980             :         column(0),
    3981             :         sourceStartColumn(0),
    3982             :         isRunOnce(false),
    3983       25640 :         noScriptRval(false)
    3984       25640 :     { }
    3985             : 
    3986             :     // Set all POD options (those not requiring reference counts, copies,
    3987             :     // rooting, or other hand-holding) to their values in |rhs|.
    3988             :     void copyPODOptions(const ReadOnlyCompileOptions& rhs);
    3989             : 
    3990             :   public:
    3991             :     // Read-only accessors for non-POD options. The proper way to set these
    3992             :     // depends on the derived type.
    3993        8530 :     bool mutedErrors() const { return mutedErrors_; }
    3994        5606 :     const char* filename() const { return filename_; }
    3995        2480 :     const char* introducerFilename() const { return introducerFilename_; }
    3996         670 :     const char16_t* sourceMapURL() const { return sourceMapURL_; }
    3997             :     virtual JSObject* element() const = 0;
    3998             :     virtual JSString* elementAttributeName() const = 0;
    3999             :     virtual JSScript* introductionScript() const = 0;
    4000             : 
    4001             :     // POD options.
    4002             :     unsigned lineno;
    4003             :     unsigned column;
    4004             :     unsigned sourceStartColumn;
    4005             :     // isRunOnce only applies to non-function scripts.
    4006             :     bool isRunOnce;
    4007             :     bool noScriptRval;
    4008             : 
    4009             :   private:
    4010             :     void operator=(const ReadOnlyCompileOptions&) = delete;
    4011             : };
    4012             : 
    4013             : /**
    4014             :  * Compilation options, with dynamic lifetime. An instance of this type
    4015             :  * makes a copy of / holds / roots all dynamically allocated resources
    4016             :  * (principals; elements; strings) that it refers to. Its destructor frees
    4017             :  * / drops / unroots them. This is heavier than CompileOptions, below, but
    4018             :  * unlike CompileOptions, it can outlive any given stack frame.
    4019             :  *
    4020             :  * Note that this *roots* any JS values it refers to - they're live
    4021             :  * unconditionally. Thus, instances of this type can't be owned, directly
    4022             :  * or indirectly, by a JavaScript object: if any value that this roots ever
    4023             :  * comes to refer to the object that owns this, then the whole cycle, and
    4024             :  * anything else it entrains, will never be freed.
    4025             :  */
    4026             : class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
    4027             : {
    4028             :     PersistentRootedObject elementRoot;
    4029             :     PersistentRootedString elementAttributeNameRoot;
    4030             :     PersistentRootedScript introductionScriptRoot;
    4031             : 
    4032             :   public:
    4033             :     // A minimal constructor, for use with OwningCompileOptions::copy. This
    4034             :     // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
    4035             :     // shouldn't be used until we've set that to something real (as |copy|
    4036             :     // will).
    4037             :     explicit OwningCompileOptions(JSContext* cx);
    4038             :     ~OwningCompileOptions();
    4039             : 
    4040         356 :     JSObject* element() const override { return elementRoot; }
    4041         356 :     JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
    4042         356 :     JSScript* introductionScript() const override { return introductionScriptRoot; }
    4043             : 
    4044             :     // Set this to a copy of |rhs|. Return false on OOM.
    4045             :     bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs);
    4046             : 
    4047             :     /* These setters make copies of their string arguments, and are fallible. */
    4048             :     bool setFile(JSContext* cx, const char* f);
    4049             :     bool setFileAndLine(JSContext* cx, const char* f, unsigned l);
    4050             :     bool setSourceMapURL(JSContext* cx, const char16_t* s);
    4051             :     bool setIntroducerFilename(JSContext* cx, const char* s);
    4052             : 
    4053             :     /* These setters are infallible, and can be chained. */
    4054             :     OwningCompileOptions& setLine(unsigned l)             { lineno = l; return *this; }
    4055          16 :     OwningCompileOptions& setElement(JSObject* e) {
    4056          16 :         elementRoot = e;
    4057          16 :         return *this;
    4058             :     }
    4059          16 :     OwningCompileOptions& setElementAttributeName(JSString* p) {
    4060          16 :         elementAttributeNameRoot = p;
    4061          16 :         return *this;
    4062             :     }
    4063          16 :     OwningCompileOptions& setIntroductionScript(JSScript* s) {
    4064          16 :         introductionScriptRoot = s;
    4065          16 :         return *this;
    4066             :     }
    4067             :     OwningCompileOptions& setMutedErrors(bool mute) {
    4068             :         mutedErrors_ = mute;
    4069             :         return *this;
    4070             :     }
    4071           0 :     OwningCompileOptions& setVersion(JSVersion v) {
    4072           0 :         version = v;
    4073           0 :         versionSet = true;
    4074           0 :         return *this;
    4075             :     }
    4076             :     OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
    4077             :     OwningCompileOptions& setColumn(unsigned c, unsigned ssc) {
    4078             :         MOZ_ASSERT(ssc <= c);
    4079             :         column = c;
    4080             :         sourceStartColumn = ssc;
    4081             :         return *this;
    4082             :     }
    4083             :     OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
    4084           0 :     OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
    4085             :     OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
    4086           0 :     OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
    4087             :     OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
    4088             :     OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
    4089             :     bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
    4090             :                              unsigned line, JSScript* script, uint32_t offset)
    4091             :     {
    4092             :         if (!setIntroducerFilename(cx, introducerFn))
    4093             :             return false;
    4094             :         introductionType = intro;
    4095             :         introductionLineno = line;
    4096             :         introductionScriptRoot = script;
    4097             :         introductionOffset = offset;
    4098             :         hasIntroductionInfo = true;
    4099             :         return true;
    4100             :     }
    4101             : 
    4102             :   private:
    4103             :     void operator=(const CompileOptions& rhs) = delete;
    4104             : };
    4105             : 
    4106             : /**
    4107             :  * Compilation options stored on the stack. An instance of this type
    4108             :  * simply holds references to dynamically allocated resources (element;
    4109             :  * filename; source map URL) that are owned by something else. If you
    4110             :  * create an instance of this type, it's up to you to guarantee that
    4111             :  * everything you store in it will outlive it.
    4112             :  */
    4113       25929 : class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions
    4114             : {
    4115             :     RootedObject elementRoot;
    4116             :     RootedString elementAttributeNameRoot;
    4117             :     RootedScript introductionScriptRoot;
    4118             : 
    4119             :   public:
    4120             :     explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN);
    4121         369 :     CompileOptions(JSContext* cx, const ReadOnlyCompileOptions& rhs)
    4122         369 :       : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
    4123         369 :         introductionScriptRoot(cx)
    4124             :     {
    4125         369 :         copyPODOptions(rhs);
    4126             : 
    4127         369 :         filename_ = rhs.filename();
    4128         369 :         introducerFilename_ = rhs.introducerFilename();
    4129         369 :         sourceMapURL_ = rhs.sourceMapURL();
    4130         369 :         elementRoot = rhs.element();
    4131         369 :         elementAttributeNameRoot = rhs.elementAttributeName();
    4132         369 :         introductionScriptRoot = rhs.introductionScript();
    4133         369 :     }
    4134             : 
    4135        3982 :     CompileOptions(JSContext* cx, const TransitiveCompileOptions& rhs)
    4136        3982 :       : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
    4137        3982 :         introductionScriptRoot(cx)
    4138             :     {
    4139        3982 :         copyPODTransitiveOptions(rhs);
    4140             : 
    4141        3982 :         filename_ = rhs.filename();
    4142        3982 :         introducerFilename_ = rhs.introducerFilename();
    4143        3982 :         sourceMapURL_ = rhs.sourceMapURL();
    4144        3982 :         elementRoot = rhs.element();
    4145        3982 :         elementAttributeNameRoot = rhs.elementAttributeName();
    4146        3982 :         introductionScriptRoot = rhs.introductionScript();
    4147        3982 :     }
    4148             : 
    4149        6165 :     JSObject* element() const override { return elementRoot; }
    4150        6172 :     JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
    4151        6177 :     JSScript* introductionScript() const override { return introductionScriptRoot; }
    4152             : 
    4153           0 :     CompileOptions& setFile(const char* f) { filename_ = f; return *this; }
    4154             :     CompileOptions& setLine(unsigned l) { lineno = l; return *this; }
    4155        2039 :     CompileOptions& setFileAndLine(const char* f, unsigned l) {
    4156        2039 :         filename_ = f; lineno = l; return *this;
    4157             :     }
    4158           0 :     CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; }
    4159          15 :     CompileOptions& setElement(JSObject* e)          { elementRoot = e; return *this; }
    4160           7 :     CompileOptions& setElementAttributeName(JSString* p) {
    4161           7 :         elementAttributeNameRoot = p;
    4162           7 :         return *this;
    4163             :     }
    4164             :     CompileOptions& setIntroductionScript(JSScript* s) {
    4165             :         introductionScriptRoot = s;
    4166             :         return *this;
    4167             :     }
    4168       11072 :     CompileOptions& setMutedErrors(bool mute) {
    4169       11072 :         mutedErrors_ = mute;
    4170       11072 :         return *this;
    4171             :     }
    4172       10364 :     CompileOptions& setVersion(JSVersion v) {
    4173       10364 :         version = v;
    4174       10364 :         versionSet = true;
    4175       10364 :         return *this;
    4176             :     }
    4177           0 :     CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
    4178        1407 :     CompileOptions& setColumn(unsigned c, unsigned ssc) {
    4179        1407 :         MOZ_ASSERT(ssc <= c);
    4180        1407 :         column = c;
    4181        1407 :         sourceStartColumn = ssc;
    4182        1407 :         return *this;
    4183             :     }
    4184          19 :     CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
    4185       20856 :     CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
    4186       20264 :     CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
    4187         144 :     CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
    4188         116 :     CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
    4189         474 :     CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
    4190           6 :     CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
    4191             :                                         unsigned line, JSScript* script, uint32_t offset)
    4192             :     {
    4193           6 :         introducerFilename_ = introducerFn;
    4194           6 :         introductionType = intro;
    4195           6 :         introductionLineno = line;
    4196           6 :         introductionScriptRoot = script;
    4197           6 :         introductionOffset = offset;
    4198           6 :         hasIntroductionInfo = true;
    4199           6 :         return *this;
    4200             :     }
    4201           2 :     CompileOptions& maybeMakeStrictMode(bool strict) {
    4202           2 :         strictOption = strictOption || strict;
    4203           2 :         return *this;
    4204             :     }
    4205             : 
    4206             :   private:
    4207             :     void operator=(const CompileOptions& rhs) = delete;
    4208             : };
    4209             : 
    4210             : /**
    4211             :  * |script| will always be set. On failure, it will be set to nullptr.
    4212             :  */
    4213             : extern JS_PUBLIC_API(bool)
    4214             : Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
    4215             :         SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
    4216             : 
    4217             : extern JS_PUBLIC_API(bool)
    4218             : Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
    4219             :         const char* bytes, size_t length, JS::MutableHandleScript script);
    4220             : 
    4221             : extern JS_PUBLIC_API(bool)
    4222             : Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
    4223             :         const char16_t* chars, size_t length, JS::MutableHandleScript script);
    4224             : 
    4225             : extern JS_PUBLIC_API(bool)
    4226             : Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
    4227             :         FILE* file, JS::MutableHandleScript script);
    4228             : 
    4229             : extern JS_PUBLIC_API(bool)
    4230             : Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
    4231             :         const char* filename, JS::MutableHandleScript script);
    4232             : 
    4233             : extern JS_PUBLIC_API(bool)
    4234             : CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
    4235             :                             SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
    4236             : 
    4237             : extern JS_PUBLIC_API(bool)
    4238             : CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
    4239             :                             const char* bytes, size_t length, JS::MutableHandleScript script);
    4240             : 
    4241             : extern JS_PUBLIC_API(bool)
    4242             : CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
    4243             :                             const char16_t* chars, size_t length, JS::MutableHandleScript script);
    4244             : 
    4245             : extern JS_PUBLIC_API(bool)
    4246             : CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
    4247             :                             FILE* file, JS::MutableHandleScript script);
    4248             : 
    4249             : extern JS_PUBLIC_API(bool)
    4250             : CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
    4251             :                             const char* filename, JS::MutableHandleScript script);
    4252             : 
    4253             : extern JS_PUBLIC_API(bool)
    4254             : CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length);
    4255             : 
    4256             : /*
    4257             :  * Off thread compilation control flow.
    4258             :  *
    4259             :  * After successfully triggering an off thread compile of a script, the
    4260             :  * callback will eventually be invoked with the specified data and a token
    4261             :  * for the compilation. The callback will be invoked while off thread,
    4262             :  * so must ensure that its operations are thread safe. Afterwards, one of the
    4263             :  * following functions must be invoked on the runtime's active thread:
    4264             :  *
    4265             :  * - FinishOffThreadScript, to get the result script (or nullptr on failure).
    4266             :  * - CancelOffThreadScript, to free the resources without creating a script.
    4267             :  *
    4268             :  * The characters passed in to CompileOffThread must remain live until the
    4269             :  * callback is invoked, and the resulting script will be rooted until the call
    4270             :  * to FinishOffThreadScript.
    4271             :  */
    4272             : 
    4273             : extern JS_PUBLIC_API(bool)
    4274             : CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
    4275             :                  const char16_t* chars, size_t length,
    4276             :                  OffThreadCompileCallback callback, void* callbackData);
    4277             : 
    4278             : extern JS_PUBLIC_API(JSScript*)
    4279             : FinishOffThreadScript(JSContext* cx, void* token);
    4280             : 
    4281             : extern JS_PUBLIC_API(void)
    4282             : CancelOffThreadScript(JSContext* cx, void* token);
    4283             : 
    4284             : extern JS_PUBLIC_API(bool)
    4285             : CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
    4286             :                        const char16_t* chars, size_t length,
    4287             :                        OffThreadCompileCallback callback, void* callbackData);
    4288             : 
    4289             : extern JS_PUBLIC_API(JSObject*)
    4290             : FinishOffThreadModule(JSContext* cx, void* token);
    4291             : 
    4292             : extern JS_PUBLIC_API(void)
    4293             : CancelOffThreadModule(JSContext* cx, void* token);
    4294             : 
    4295             : extern JS_PUBLIC_API(bool)
    4296             : DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
    4297             :                       mozilla::Vector<uint8_t>& buffer /* TranscodeBuffer& */, size_t cursor,
    4298             :                       OffThreadCompileCallback callback, void* callbackData);
    4299             : 
    4300             : extern JS_PUBLIC_API(bool)
    4301             : DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options,
    4302             :                       const mozilla::Range<uint8_t>& range /* TranscodeRange& */,
    4303             :                       OffThreadCompileCallback callback, void* callbackData);
    4304             : 
    4305             : extern JS_PUBLIC_API(JSScript*)
    4306             : FinishOffThreadScriptDecoder(JSContext* cx, void* token);
    4307             : 
    4308             : extern JS_PUBLIC_API(void)
    4309             : CancelOffThreadScriptDecoder(JSContext* cx, void* token);
    4310             : 
    4311             : extern JS_PUBLIC_API(bool)
    4312             : DecodeMultiOffThreadScripts(JSContext* cx, const ReadOnlyCompileOptions& options,
    4313             :                             mozilla::Vector<TranscodeSource>& sources,
    4314             :                             OffThreadCompileCallback callback, void* callbackData);
    4315             : 
    4316             : extern JS_PUBLIC_API(bool)
    4317             : FinishMultiOffThreadScriptsDecoder(JSContext* cx, void* token, JS::MutableHandle<JS::ScriptVector> scripts);
    4318             : 
    4319             : extern JS_PUBLIC_API(void)
    4320             : CancelMultiOffThreadScriptsDecoder(JSContext* cx, void* token);
    4321             : 
    4322             : /**
    4323             :  * Compile a function with envChain plus the global as its scope chain.
    4324             :  * envChain must contain objects in the current compartment of cx.  The actual
    4325             :  * scope chain used for the function will consist of With wrappers for those
    4326             :  * objects, followed by the current global of the compartment cx is in.  This
    4327             :  * global must not be explicitly included in the scope chain.
    4328             :  */
    4329             : extern JS_PUBLIC_API(bool)
    4330             : CompileFunction(JSContext* cx, AutoObjectVector& envChain,
    4331             :                 const ReadOnlyCompileOptions& options,
    4332             :                 const char* name, unsigned nargs, const char* const* argnames,
    4333             :                 const char16_t* chars, size_t length, JS::MutableHandleFunction fun);
    4334             : 
    4335             : /**
    4336             :  * Same as above, but taking a SourceBufferHolder for the function body.
    4337             :  */
    4338             : extern JS_PUBLIC_API(bool)
    4339             : CompileFunction(JSContext* cx, AutoObjectVector& envChain,
    4340             :                 const ReadOnlyCompileOptions& options,
    4341             :                 const char* name, unsigned nargs, const char* const* argnames,
    4342             :                 SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun);
    4343             : 
    4344             : /**
    4345             :  * Same as above, but taking a const char * for the function body.
    4346             :  */
    4347             : extern JS_PUBLIC_API(bool)
    4348             : CompileFunction(JSContext* cx, AutoObjectVector& envChain,
    4349             :                 const ReadOnlyCompileOptions& options,
    4350             :                 const char* name, unsigned nargs, const char* const* argnames,
    4351             :                 const char* bytes, size_t length, JS::MutableHandleFunction fun);
    4352             : 
    4353             : } /* namespace JS */
    4354             : 
    4355             : extern JS_PUBLIC_API(JSString*)
    4356             : JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script, const char* name, unsigned indent);
    4357             : 
    4358             : /*
    4359             :  * API extension: OR this into indent to avoid pretty-printing the decompiled
    4360             :  * source resulting from JS_DecompileFunction.
    4361             :  */
    4362             : #define JS_DONT_PRETTY_PRINT    ((unsigned)0x8000)
    4363             : 
    4364             : extern JS_PUBLIC_API(JSString*)
    4365             : JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
    4366             : 
    4367             : 
    4368             : /*
    4369             :  * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
    4370             :  * they use the global as the scope, or they take an AutoObjectVector of objects
    4371             :  * to use as the scope chain.  In the former case, the global is also used as
    4372             :  * the "this" keyword value and the variables object (ECMA parlance for where
    4373             :  * 'var' and 'function' bind names) of the execution context for script.  In the
    4374             :  * latter case, the first object in the provided list is used, unless the list
    4375             :  * is empty, in which case the global is used.
    4376             :  *
    4377             :  * Why a runtime option?  The alternative is to add APIs duplicating those
    4378             :  * for the other value of flags, and that doesn't seem worth the code bloat
    4379             :  * cost.  Such new entry points would probably have less obvious names, too, so
    4380             :  * would not tend to be used.  The ContextOptionsRef adjustment, OTOH, can be
    4381             :  * more easily hacked into existing code that does not depend on the bug; such
    4382             :  * code can continue to use the familiar JS::Evaluate, etc., entry points.
    4383             :  */
    4384             : 
    4385             : /**
    4386             :  * Evaluate a script in the scope of the current global of cx.
    4387             :  */
    4388             : extern JS_PUBLIC_API(bool)
    4389             : JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval);
    4390             : 
    4391             : extern JS_PUBLIC_API(bool)
    4392             : JS_ExecuteScript(JSContext* cx, JS::HandleScript script);
    4393             : 
    4394             : /**
    4395             :  * As above, but providing an explicit scope chain.  envChain must not include
    4396             :  * the global object on it; that's implicit.  It needs to contain the other
    4397             :  * objects that should end up on the script's scope chain.
    4398             :  */
    4399             : extern JS_PUBLIC_API(bool)
    4400             : JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
    4401             :                  JS::HandleScript script, JS::MutableHandleValue rval);
    4402             : 
    4403             : extern JS_PUBLIC_API(bool)
    4404             : JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script);
    4405             : 
    4406             : namespace JS {
    4407             : 
    4408             : /**
    4409             :  * Like the above, but handles a cross-compartment script. If the script is
    4410             :  * cross-compartment, it is cloned into the current compartment before executing.
    4411             :  */
    4412             : extern JS_PUBLIC_API(bool)
    4413             : CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script,
    4414             :                       JS::MutableHandleValue rval);
    4415             : 
    4416             : /**
    4417             :  * Like CloneAndExecuteScript above, but allows executing under a non-syntactic
    4418             :  * environment chain.
    4419             :  */
    4420             : extern JS_PUBLIC_API(bool)
    4421             : CloneAndExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain,
    4422             :                       JS::Handle<JSScript*> script,
    4423             :                       JS::MutableHandleValue rval);
    4424             : 
    4425             : } /* namespace JS */
    4426             : 
    4427             : namespace JS {
    4428             : 
    4429             : /**
    4430             :  * Evaluate the given source buffer in the scope of the current global of cx.
    4431             :  */
    4432             : extern JS_PUBLIC_API(bool)
    4433             : Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
    4434             :          SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
    4435             : 
    4436             : /**
    4437             :  * As above, but providing an explicit scope chain.  envChain must not include
    4438             :  * the global object on it; that's implicit.  It needs to contain the other
    4439             :  * objects that should end up on the script's scope chain.
    4440             :  */
    4441             : extern JS_PUBLIC_API(bool)
    4442             : Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
    4443             :          SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
    4444             : 
    4445             : /**
    4446             :  * Evaluate the given character buffer in the scope of the current global of cx.
    4447             :  */
    4448             : extern JS_PUBLIC_API(bool)
    4449             : Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
    4450             :          const char16_t* chars, size_t length, JS::MutableHandleValue rval);
    4451             : 
    4452             : /**
    4453             :  * As above, but providing an explicit scope chain.  envChain must not include
    4454             :  * the global object on it; that's implicit.  It needs to contain the other
    4455             :  * objects that should end up on the script's scope chain.
    4456             :  */
    4457             : extern JS_PUBLIC_API(bool)
    4458             : Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options,
    4459             :          const char16_t* chars, size_t length, JS::MutableHandleValue rval);
    4460             : 
    4461             : /**
    4462             :  * Evaluate the given byte buffer in the scope of the current global of cx.
    4463             :  */
    4464             : extern JS_PUBLIC_API(bool)
    4465             : Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
    4466             :          const char* bytes, size_t length, JS::MutableHandleValue rval);
    4467             : 
    4468             : /**
    4469             :  * Evaluate the given file in the scope of the current global of cx.
    4470             :  */
    4471             : extern JS_PUBLIC_API(bool)
    4472             : Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
    4473             :          const char* filename, JS::MutableHandleValue rval);
    4474             : 
    4475             : /**
    4476             :  * Get the HostResolveImportedModule hook for a global.
    4477             :  */
    4478             : extern JS_PUBLIC_API(JSFunction*)
    4479             : GetModuleResolveHook(JSContext* cx);
    4480             : 
    4481             : /**
    4482             :  * Set the HostResolveImportedModule hook for a global to the given function.
    4483             :  */
    4484             : extern JS_PUBLIC_API(void)
    4485             : SetModuleResolveHook(JSContext* cx, JS::HandleFunction func);
    4486             : 
    4487             : /**
    4488             :  * Parse the given source buffer as a module in the scope of the current global
    4489             :  * of cx and return a source text module record.
    4490             :  */
    4491             : extern JS_PUBLIC_API(bool)
    4492             : CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
    4493             :               SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
    4494             : 
    4495             : /**
    4496             :  * Set the [[HostDefined]] field of a source text module record to the given
    4497             :  * value.
    4498             :  */
    4499             : extern JS_PUBLIC_API(void)
    4500             : SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
    4501             : 
    4502             : /**
    4503             :  * Get the [[HostDefined]] field of a source text module record.
    4504             :  */
    4505             : extern JS_PUBLIC_API(JS::Value)
    4506             : GetModuleHostDefinedField(JSObject* module);
    4507             : 
    4508             : /*
    4509             :  * Perform the ModuleDeclarationInstantiation operation on on the give source
    4510             :  * text module record.
    4511             :  *
    4512             :  * This transitively resolves all module dependencies (calling the
    4513             :  * HostResolveImportedModule hook) and initializes the environment record for
    4514             :  * the module.
    4515             :  */
    4516             : extern JS_PUBLIC_API(bool)
    4517             : ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord);
    4518             : 
    4519             : /*
    4520             :  * Perform the ModuleEvaluation operation on on the give source text module
    4521             :  * record.
    4522             :  *
    4523             :  * This does nothing if this module has already been evaluated. Otherwise, it
    4524             :  * transitively evaluates all dependences of this module and then evaluates this
    4525             :  * module.
    4526             :  *
    4527             :  * ModuleDeclarationInstantiation must have completed prior to calling this.
    4528             :  */
    4529             : extern JS_PUBLIC_API(bool)
    4530             : ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord);
    4531             : 
    4532             : /*
    4533             :  * Get a list of the module specifiers used by a source text module
    4534             :  * record to request importation of modules.
    4535             :  *
    4536             :  * The result is a JavaScript array of string values.  To extract the individual
    4537             :  * values use only JS_GetArrayLength and JS_GetElement with indices 0 to
    4538             :  * length - 1.
    4539             :  */
    4540             : extern JS_PUBLIC_API(JSObject*)
    4541             : GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
    4542             : 
    4543             : /*
    4544             :  * Get the script associated with a module.
    4545             :  */
    4546             : extern JS_PUBLIC_API(JSScript*)
    4547             : GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord);
    4548             : 
    4549             : } /* namespace JS */
    4550             : 
    4551             : extern JS_PUBLIC_API(bool)
    4552             : JS_CheckForInterrupt(JSContext* cx);
    4553             : 
    4554             : /*
    4555             :  * These functions allow setting an interrupt callback that will be called
    4556             :  * from the JS thread some time after any thread triggered the callback using
    4557             :  * JS_RequestInterruptCallback(cx).
    4558             :  *
    4559             :  * To schedule the GC and for other activities the engine internally triggers
    4560             :  * interrupt callbacks. The embedding should thus not rely on callbacks being
    4561             :  * triggered through the external API only.
    4562             :  *
    4563             :  * Important note: Additional callbacks can occur inside the callback handler
    4564             :  * if it re-enters the JS engine. The embedding must ensure that the callback
    4565             :  * is disconnected before attempting such re-entry.
    4566             :  */
    4567             : extern JS_PUBLIC_API(bool)
    4568             : JS_AddInterruptCallback(JSContext* cx, JSInterruptCallback callback);
    4569             : 
    4570             : extern JS_PUBLIC_API(bool)
    4571             : JS_DisableInterruptCallback(JSContext* cx);
    4572             : 
    4573             : extern JS_PUBLIC_API(void)
    4574             : JS_ResetInterruptCallback(JSContext* cx, bool enable);
    4575             : 
    4576             : extern JS_PUBLIC_API(void)
    4577             : JS_RequestInterruptCallback(JSContext* cx);
    4578             : 
    4579             : namespace JS {
    4580             : 
    4581             : /**
    4582             :  * Sets the callback that's invoked whenever an incumbent global is required.
    4583             :  *
    4584             :  * SpiderMonkey doesn't itself have a notion of incumbent globals as defined
    4585             :  * by the html spec, so we need the embedding to provide this.
    4586             :  * See dom/base/ScriptSettings.h for details.
    4587             :  */
    4588             : extern JS_PUBLIC_API(void)
    4589             : SetGetIncumbentGlobalCallback(JSContext* cx, JSGetIncumbentGlobalCallback callback);
    4590             : 
    4591             : /**
    4592             :  * Sets the callback that's invoked whenever a Promise job should be enqeued.
    4593             :  *
    4594             :  * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead,
    4595             :  * using this function the embedding can provide a callback to do that
    4596             :  * scheduling. The provided `callback` is invoked with the promise job,
    4597             :  * the corresponding Promise's allocation stack, and the `data` pointer
    4598             :  * passed here as arguments.
    4599             :  */
    4600             : extern JS_PUBLIC_API(void)
    4601             : SetEnqueuePromiseJobCallback(JSContext* cx, JSEnqueuePromiseJobCallback callback,
    4602             :                              void* data = nullptr);
    4603             : 
    4604             : /**
    4605             :  * Sets the callback that's invoked whenever a Promise is rejected without
    4606             :  * a rejection handler, and when a Promise that was previously rejected
    4607             :  * without a handler gets a handler attached.
    4608             :  */
    4609             : extern JS_PUBLIC_API(void)
    4610             : SetPromiseRejectionTrackerCallback(JSContext* cx, JSPromiseRejectionTrackerCallback callback,
    4611             :                                    void* data = nullptr);
    4612             : 
    4613             : /**
    4614             :  * Returns a new instance of the Promise builtin class in the current
    4615             :  * compartment, with the right slot layout.
    4616             :  *
    4617             :  * The `executor` can be a `nullptr`. In that case, the only way to resolve or
    4618             :  * reject the returned promise is via the `JS::ResolvePromise` and
    4619             :  * `JS::RejectPromise` JSAPI functions.
    4620             :  *
    4621             :  * If a `proto` is passed, that gets set as the instance's [[Prototype]]
    4622             :  * instead of the original value of `Promise.prototype`.
    4623             :  */
    4624             : extern JS_PUBLIC_API(JSObject*)
    4625             : NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr);
    4626             : 
    4627             : /**
    4628             :  * Returns true if the given object is an unwrapped PromiseObject, false
    4629             :  * otherwise.
    4630             :  */
    4631             : extern JS_PUBLIC_API(bool)
    4632             : IsPromiseObject(JS::HandleObject obj);
    4633             : 
    4634             : /**
    4635             :  * Returns the current compartment's original Promise constructor.
    4636             :  */
    4637             : extern JS_PUBLIC_API(JSObject*)
    4638             : GetPromiseConstructor(JSContext* cx);
    4639             : 
    4640             : /**
    4641             :  * Returns the current compartment's original Promise.prototype.
    4642             :  */
    4643             : extern JS_PUBLIC_API(JSObject*)
    4644             : GetPromisePrototype(JSContext* cx);
    4645             : 
    4646             : // Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h.
    4647             : enum class PromiseState {
    4648             :     Pending,
    4649             :     Fulfilled,
    4650             :     Rejected
    4651             : };
    4652             : 
    4653             : /**
    4654             :  * Returns the given Promise's state as a JS::PromiseState enum value.
    4655             :  *
    4656             :  * Returns JS::PromiseState::Pending if the given object is a wrapper that
    4657             :  * can't safely be unwrapped.
    4658             :  */
    4659             : extern JS_PUBLIC_API(PromiseState)
    4660             : GetPromiseState(JS::HandleObject promise);
    4661             : 
    4662             : /**
    4663             :  * Returns the given Promise's process-unique ID.
    4664             :  */
    4665             : JS_PUBLIC_API(uint64_t)
    4666             : GetPromiseID(JS::HandleObject promise);
    4667             : 
    4668             : /**
    4669             :  * Returns the given Promise's result: either the resolution value for
    4670             :  * fulfilled promises, or the rejection reason for rejected ones.
    4671             :  */
    4672             : extern JS_PUBLIC_API(JS::Value)
    4673             : GetPromiseResult(JS::HandleObject promise);
    4674             : 
    4675             : /**
    4676             :  * Returns a js::SavedFrame linked list of the stack that lead to the given
    4677             :  * Promise's allocation.
    4678             :  */
    4679             : extern JS_PUBLIC_API(JSObject*)
    4680             : GetPromiseAllocationSite(JS::HandleObject promise);
    4681             : 
    4682             : extern JS_PUBLIC_API(JSObject*)
    4683             : GetPromiseResolutionSite(JS::HandleObject promise);
    4684             : 
    4685             : #ifdef DEBUG
    4686             : extern JS_PUBLIC_API(void)
    4687             : DumpPromiseAllocationSite(JSContext* cx, JS::HandleObject promise);
    4688             : 
    4689             : extern JS_PUBLIC_API(void)
    4690             : DumpPromiseResolutionSite(JSContext* cx, JS::HandleObject promise);
    4691             : #endif
    4692             : 
    4693             : /**
    4694             :  * Calls the current compartment's original Promise.resolve on the original
    4695             :  * Promise constructor, with `resolutionValue` passed as an argument.
    4696             :  */
    4697             : extern JS_PUBLIC_API(JSObject*)
    4698             : CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue);
    4699             : 
    4700             : /**
    4701             :  * Calls the current compartment's original Promise.reject on the original
    4702             :  * Promise constructor, with `resolutionValue` passed as an argument.
    4703             :  */
    4704             : extern JS_PUBLIC_API(JSObject*)
    4705             : CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue);
    4706             : 
    4707             : /**
    4708             :  * Resolves the given Promise with the given `resolutionValue`.
    4709             :  *
    4710             :  * Calls the `resolve` function that was passed to the executor function when
    4711             :  * the Promise was created.
    4712             :  */
    4713             : extern JS_PUBLIC_API(bool)
    4714             : ResolvePromise(JSContext* cx, JS::HandleObject promiseObj, JS::HandleValue resolutionValue);
    4715             : 
    4716             : /**
    4717             :  * Rejects the given `promise` with the given `rejectionValue`.
    4718             :  *
    4719             :  * Calls the `reject` function that was passed to the executor function when
    4720             :  * the Promise was created.
    4721             :  */
    4722             : extern JS_PUBLIC_API(bool)
    4723             : RejectPromise(JSContext* cx, JS::HandleObject promiseObj, JS::HandleValue rejectionValue);
    4724             : 
    4725             : /**
    4726             :  * Calls the current compartment's original Promise.prototype.then on the
    4727             :  * given `promise`, with `onResolve` and `onReject` passed as arguments.
    4728             :  *
    4729             :  * Asserts if the passed-in `promise` object isn't an unwrapped instance of
    4730             :  * `Promise` or a subclass or `onResolve` and `onReject` aren't both either
    4731             :  * `nullptr` or callable objects.
    4732             :  */
    4733             : extern JS_PUBLIC_API(JSObject*)
    4734             : CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise,
    4735             :                         JS::HandleObject onResolve, JS::HandleObject onReject);
    4736             : 
    4737             : /**
    4738             :  * Unforgeable, optimized version of the JS builtin Promise.prototype.then.
    4739             :  *
    4740             :  * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue
    4741             :  * as reactions for that promise. In difference to Promise.prototype.then,
    4742             :  * this doesn't create and return a new Promise instance.
    4743             :  *
    4744             :  * Asserts if the passed-in `promise` object isn't an unwrapped instance of
    4745             :  * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable
    4746             :  * objects.
    4747             :  */
    4748             : extern JS_PUBLIC_API(bool)
    4749             : AddPromiseReactions(JSContext* cx, JS::HandleObject promise,
    4750             :                     JS::HandleObject onResolve, JS::HandleObject onReject);
    4751             : 
    4752             : /**
    4753             :  * Unforgeable version of the JS builtin Promise.all.
    4754             :  *
    4755             :  * Takes an AutoObjectVector of Promise objects and returns a promise that's
    4756             :  * resolved with an array of resolution values when all those promises have
    4757             :  * been resolved, or rejected with the rejection value of the first rejected
    4758             :  * promise.
    4759             :  *
    4760             :  * Asserts that all objects in the `promises` vector are, maybe wrapped,
    4761             :  * instances of `Promise` or a subclass of `Promise`.
    4762             :  */
    4763             : extern JS_PUBLIC_API(JSObject*)
    4764             : GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
    4765             : 
    4766             : /**
    4767             :  * An AsyncTask represents a SpiderMonkey-internal operation that starts on a
    4768             :  * JSContext's owner thread, possibly executes on other threads, completes, and
    4769             :  * then needs to be scheduled to run again on the JSContext's owner thread. The
    4770             :  * embedding provides for this final dispatch back to the JSContext's owner
    4771             :  * thread by calling methods on this interface when requested.
    4772             :  */
    4773             : struct JS_PUBLIC_API(AsyncTask)
    4774             : {
    4775           0 :     AsyncTask() : user(nullptr) {}
    4776           0 :     virtual ~AsyncTask() {}
    4777             : 
    4778             :     /**
    4779             :      * After the FinishAsyncTaskCallback is called and succeeds, one of these
    4780             :      * two functions will be called on the original JSContext's owner thread.
    4781             :      */
    4782             :     virtual void finish(JSContext* cx) = 0;
    4783             :     virtual void cancel(JSContext* cx) = 0;
    4784             : 
    4785             :     /* The embedding may use this field to attach arbitrary data to a task. */
    4786             :     void* user;
    4787             : };
    4788             : 
    4789             : /**
    4790             :  * A new AsyncTask object, created inside SpiderMonkey on the JSContext's owner
    4791             :  * thread, will be passed to the StartAsyncTaskCallback before it is dispatched
    4792             :  * to another thread. The embedding may use the AsyncTask::user field to attach
    4793             :  * additional task state.
    4794             :  *
    4795             :  * If this function succeeds, SpiderMonkey will call the FinishAsyncTaskCallback
    4796             :  * at some point in the future. Otherwise, FinishAsyncTaskCallback will *not*
    4797             :  * be called. SpiderMonkey assumes that, if StartAsyncTaskCallback fails, it is
    4798             :  * because the JSContext is being shut down.
    4799             :  */
    4800             : typedef bool
    4801             : (*StartAsyncTaskCallback)(JSContext* cx, AsyncTask* task);
    4802             : 
    4803             : /**
    4804             :  * The FinishAsyncTaskCallback may be called from any thread and will only be
    4805             :  * passed AsyncTasks that have already been started via StartAsyncTaskCallback.
    4806             :  * If the embedding returns 'true', indicating success, the embedding must call
    4807             :  * either task->finish() or task->cancel() on the JSContext's owner thread at
    4808             :  * some point in the future.
    4809             :  */
    4810             : typedef bool
    4811             : (*FinishAsyncTaskCallback)(AsyncTask* task);
    4812             : 
    4813             : /**
    4814             :  * Set the above callbacks for the given context.
    4815             :  */
    4816             : extern JS_PUBLIC_API(void)
    4817             : SetAsyncTaskCallbacks(JSContext* cx, StartAsyncTaskCallback start, FinishAsyncTaskCallback finish);
    4818             : 
    4819             : /**
    4820             :  * This class can be used to store a pointer to the youngest frame of a saved
    4821             :  * stack in the specified JSContext. This reference will be picked up by any new
    4822             :  * calls performed until the class is destroyed, with the specified asyncCause,
    4823             :  * that must not be empty.
    4824             :  *
    4825             :  * Any stack capture initiated during these new calls will go through the async
    4826             :  * stack instead of the current stack.
    4827             :  *
    4828             :  * Capturing the stack before a new call is performed will not be affected.
    4829             :  *
    4830             :  * The provided chain of SavedFrame objects can live in any compartment,
    4831             :  * although it will be copied to the compartment where the stack is captured.
    4832             :  *
    4833             :  * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
    4834             :  * stack frames.
    4835             :  */
    4836             : class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls)
    4837             : {
    4838             :     JSContext* cx;
    4839             :     RootedObject oldAsyncStack;
    4840             :     const char* oldAsyncCause;
    4841             :     bool oldAsyncCallIsExplicit;
    4842             : 
    4843             :   public:
    4844             :     enum class AsyncCallKind {
    4845             :         // The ordinary kind of call, where we may apply an async
    4846             :         // parent if there is no ordinary parent.
    4847             :         IMPLICIT,
    4848             :         // An explicit async parent, e.g., callFunctionWithAsyncStack,
    4849             :         // where we always want to override any ordinary parent.
    4850             :         EXPLICIT
    4851             :     };
    4852             : 
    4853             :     // The stack parameter cannot be null by design, because it would be
    4854             :     // ambiguous whether that would clear any scheduled async stack and make the
    4855             :     // normal stack reappear in the new call, or just keep the async stack
    4856             :     // already scheduled for the new call, if any.
    4857             :     //
    4858             :     // asyncCause is owned by the caller and its lifetime must outlive the
    4859             :     // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
    4860             :     // encouraged that asyncCause be a string constant or similar statically
    4861             :     // allocated string.
    4862             :     AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack,
    4863             :                                  const char* asyncCause,
    4864             :                                  AsyncCallKind kind = AsyncCallKind::IMPLICIT);
    4865             :     ~AutoSetAsyncStackForNewCalls();
    4866             : };
    4867             : 
    4868             : } // namespace JS
    4869             : 
    4870             : /************************************************************************/
    4871             : 
    4872             : /*
    4873             :  * Strings.
    4874             :  *
    4875             :  * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
    4876             :  * but on error (signified by null return), it leaves chars owned by the
    4877             :  * caller. So the caller must free bytes in the error case, if it has no use
    4878             :  * for them. In contrast, all the JS_New*StringCopy* functions do not take
    4879             :  * ownership of the character memory passed to them -- they copy it.
    4880             :  */
    4881             : extern JS_PUBLIC_API(JSString*)
    4882             : JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
    4883             : 
    4884             : extern JS_PUBLIC_API(JSString*)
    4885             : JS_NewStringCopyZ(JSContext* cx, const char* s);
    4886             : 
    4887             : extern JS_PUBLIC_API(JSString*)
    4888             : JS_NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ s);
    4889             : 
    4890             : extern JS_PUBLIC_API(JSString*)
    4891             : JS_NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars s);
    4892             : 
    4893             : extern JS_PUBLIC_API(JSString*)
    4894             : JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
    4895             : 
    4896             : extern JS_PUBLIC_API(JSString*)
    4897             : JS_AtomizeStringN(JSContext* cx, const char* s, size_t length);
    4898             : 
    4899             : extern JS_PUBLIC_API(JSString*)
    4900             : JS_AtomizeString(JSContext* cx, const char* s);
    4901             : 
    4902             : extern JS_PUBLIC_API(JSString*)
    4903             : JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length);
    4904             : 
    4905             : extern JS_PUBLIC_API(JSString*)
    4906             : JS_AtomizeAndPinString(JSContext* cx, const char* s);
    4907             : 
    4908             : extern JS_PUBLIC_API(JSString*)
    4909             : JS_NewUCString(JSContext* cx, char16_t* chars, size_t length);
    4910             : 
    4911             : extern JS_PUBLIC_API(JSString*)
    4912             : JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n);
    4913             : 
    4914             : extern JS_PUBLIC_API(JSString*)
    4915             : JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s);
    4916             : 
    4917             : extern JS_PUBLIC_API(JSString*)
    4918             : JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length);
    4919             : 
    4920             : extern JS_PUBLIC_API(JSString*)
    4921             : JS_AtomizeUCString(JSContext* cx, const char16_t* s);
    4922             : 
    4923             : extern JS_PUBLIC_API(JSString*)
    4924             : JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length);
    4925             : 
    4926             : extern JS_PUBLIC_API(JSString*)
    4927             : JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s);
    4928             : 
    4929             : extern JS_PUBLIC_API(bool)
    4930             : JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result);
    4931             : 
    4932             : extern JS_PUBLIC_API(bool)
    4933             : JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match);
    4934             : 
    4935             : extern JS_PUBLIC_API(size_t)
    4936             : JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote);
    4937             : 
    4938             : extern JS_PUBLIC_API(bool)
    4939             : JS_FileEscapedString(FILE* fp, JSString* str, char quote);
    4940             : 
    4941             : /*
    4942             :  * Extracting string characters and length.
    4943             :  *
    4944             :  * While getting the length of a string is infallible, getting the chars can
    4945             :  * fail. As indicated by the lack of a JSContext parameter, there are two
    4946             :  * special cases where getting the chars is infallible:
    4947             :  *
    4948             :  * The first case is for strings that have been atomized, e.g. directly by
    4949             :  * JS_AtomizeAndPinString or implicitly because it is stored in a jsid.
    4950             :  *
    4951             :  * The second case is "flat" strings that have been explicitly prepared in a
    4952             :  * fallible context by JS_FlattenString. To catch errors, a separate opaque
    4953             :  * JSFlatString type is returned by JS_FlattenString and expected by
    4954             :  * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
    4955             :  * distinction: the input and output of JS_FlattenString are the same actual
    4956             :  * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be
    4957             :  * used to make a debug-checked cast. Example:
    4958             :  *
    4959             :  *   // in a fallible context
    4960             :  *   JSFlatString* fstr = JS_FlattenString(cx, str);
    4961             :  *   if (!fstr)
    4962             :  *     return false;
    4963             :  *   MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
    4964             :  *
    4965             :  *   // in an infallible context, for the same 'str'
    4966             :  *   AutoCheckCannotGC nogc;
    4967             :  *   const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
    4968             :  *   MOZ_ASSERT(chars);
    4969             :  *
    4970             :  * Flat strings and interned strings are always null-terminated, so
    4971             :  * JS_FlattenString can be used to get a null-terminated string.
    4972             :  *
    4973             :  * Additionally, string characters are stored as either Latin1Char (8-bit)
    4974             :  * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then
    4975             :  * call either the Latin1* or TwoByte* functions. Some functions like
    4976             :  * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
    4977             :  * strings.
    4978             :  */
    4979             : 
    4980             : extern JS_PUBLIC_API(size_t)
    4981             : JS_GetStringLength(JSString* str);
    4982             : 
    4983             : extern JS_PUBLIC_API(bool)
    4984             : JS_StringIsFlat(JSString* str);
    4985             : 
    4986             : /** Returns true iff the string's characters are stored as Latin1. */
    4987             : extern JS_PUBLIC_API(bool)
    4988             : JS_StringHasLatin1Chars(JSString* str);
    4989             : 
    4990             : extern JS_PUBLIC_API(const JS::Latin1Char*)
    4991             : JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
    4992             :                                  size_t* length);
    4993             : 
    4994             : extern JS_PUBLIC_API(const char16_t*)
    4995             : JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
    4996             :                                   size_t* length);
    4997             : 
    4998             : extern JS_PUBLIC_API(bool)
    4999             : JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res);
    5000             : 
    5001             : extern JS_PUBLIC_API(char16_t)
    5002             : JS_GetFlatStringCharAt(JSFlatString* str, size_t index);
    5003             : 
    5004             : extern JS_PUBLIC_API(const char16_t*)
    5005             : JS_GetTwoByteExternalStringChars(JSString* str);
    5006             : 
    5007             : extern JS_PUBLIC_API(bool)
    5008             : JS_CopyStringChars(JSContext* cx, mozilla::Range<char16_t> dest, JSString* str);
    5009             : 
    5010             : extern JS_PUBLIC_API(JSFlatString*)
    5011             : JS_FlattenString(JSContext* cx, JSString* str);
    5012             : 
    5013             : extern JS_PUBLIC_API(const JS::Latin1Char*)
    5014             : JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
    5015             : 
    5016             : extern JS_PUBLIC_API(const char16_t*)
    5017             : JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
    5018             : 
    5019             : static MOZ_ALWAYS_INLINE JSFlatString*
    5020        3353 : JSID_TO_FLAT_STRING(jsid id)
    5021             : {
    5022        3353 :     MOZ_ASSERT(JSID_IS_STRING(id));
    5023        3353 :     return (JSFlatString*)(JSID_BITS(id));
    5024             : }
    5025             : 
    5026             : static MOZ_ALWAYS_INLINE JSFlatString*
    5027           0 : JS_ASSERT_STRING_IS_FLAT(JSString* str)
    5028             : {
    5029           0 :     MOZ_ASSERT(JS_StringIsFlat(str));
    5030           0 :     return (JSFlatString*)str;
    5031             : }
    5032             : 
    5033             : static MOZ_ALWAYS_INLINE JSString*
    5034           0 : JS_FORGET_STRING_FLATNESS(JSFlatString* fstr)
    5035             : {
    5036           0 :     return (JSString*)fstr;
    5037             : }
    5038             : 
    5039             : /*
    5040             :  * Additional APIs that avoid fallibility when given a flat string.
    5041             :  */
    5042             : 
    5043             : extern JS_PUBLIC_API(bool)
    5044             : JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes);
    5045             : 
    5046             : extern JS_PUBLIC_API(size_t)
    5047             : JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote);
    5048             : 
    5049             : /**
    5050             :  * Create a dependent string, i.e., a string that owns no character storage,
    5051             :  * but that refers to a slice of another string's chars.  Dependent strings
    5052             :  * are mutable by definition, so the thread safety comments above apply.
    5053             :  */
    5054             : extern JS_PUBLIC_API(JSString*)
    5055             : JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start,
    5056             :                       size_t length);
    5057             : 
    5058             : /**
    5059             :  * Concatenate two strings, possibly resulting in a rope.
    5060             :  * See above for thread safety comments.
    5061             :  */
    5062             : extern JS_PUBLIC_API(JSString*)
    5063             : JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right);
    5064             : 
    5065             : /**
    5066             :  * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
    5067             :  * the call; on return, *dstlenp contains the number of characters actually
    5068             :  * stored. To determine the necessary destination buffer size, make a sizing
    5069             :  * call that passes nullptr for dst.
    5070             :  *
    5071             :  * On errors, the functions report the error. In that case, *dstlenp contains
    5072             :  * the number of characters or bytes transferred so far.  If cx is nullptr, no
    5073             :  * error is reported on failure, and the functions simply return false.
    5074             :  *
    5075             :  * NB: This function does not store an additional zero byte or char16_t after the
    5076             :  * transcoded string.
    5077             :  */
    5078             : JS_PUBLIC_API(bool)
    5079             : JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst,
    5080             :                size_t* dstlenp);
    5081             : 
    5082             : /**
    5083             :  * A variation on JS_EncodeCharacters where a null terminated string is
    5084             :  * returned that you are expected to call JS_free on when done.
    5085             :  */
    5086             : JS_PUBLIC_API(char*)
    5087             : JS_EncodeString(JSContext* cx, JSString* str);
    5088             : 
    5089             : /**
    5090             :  * Same behavior as JS_EncodeString(), but encode into UTF-8 string
    5091             :  */
    5092             : JS_PUBLIC_API(char*)
    5093             : JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str);
    5094             : 
    5095             : /**
    5096             :  * Get number of bytes in the string encoding (without accounting for a
    5097             :  * terminating zero bytes. The function returns (size_t) -1 if the string
    5098             :  * can not be encoded into bytes and reports an error using cx accordingly.
    5099             :  */
    5100             : JS_PUBLIC_API(size_t)
    5101             : JS_GetStringEncodingLength(JSContext* cx, JSString* str);
    5102             : 
    5103             : /**
    5104             :  * Encode string into a buffer. The function does not stores an additional
    5105             :  * zero byte. The function returns (size_t) -1 if the string can not be
    5106             :  * encoded into bytes with no error reported. Otherwise it returns the number
    5107             :  * of bytes that are necessary to encode the string. If that exceeds the
    5108             :  * length parameter, the string will be cut and only length bytes will be
    5109             :  * written into the buffer.
    5110             :  */
    5111             : JS_PUBLIC_API(size_t)
    5112             : JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length);
    5113             : 
    5114             : class MOZ_RAII JSAutoByteString
    5115             : {
    5116             :   public:
    5117        1619 :     JSAutoByteString(JSContext* cx, JSString* str
    5118             :                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    5119        1619 :       : mBytes(JS_EncodeString(cx, str))
    5120             :     {
    5121        1619 :         MOZ_ASSERT(cx);
    5122        1619 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    5123        1619 :     }
    5124             : 
    5125        3070 :     explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
    5126        3070 :       : mBytes(nullptr)
    5127             :     {
    5128        3070 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    5129        3070 :     }
    5130             : 
    5131        9378 :     ~JSAutoByteString() {
    5132        4689 :         JS_free(nullptr, mBytes);
    5133        4689 :     }
    5134             : 
    5135             :     /* Take ownership of the given byte array. */
    5136           0 :     void initBytes(JS::UniqueChars&& bytes) {
    5137           0 :         MOZ_ASSERT(!mBytes);
    5138           0 :         mBytes = bytes.release();
    5139           0 :     }
    5140             : 
    5141        3032 :     char* encodeLatin1(JSContext* cx, JSString* str) {
    5142        3032 :         MOZ_ASSERT(!mBytes);
    5143        3032 :         MOZ_ASSERT(cx);
    5144        3032 :         mBytes = JS_EncodeString(cx, str);
    5145        3032 :         return mBytes;
    5146             :     }
    5147             : 
    5148          36 :     char* encodeUtf8(JSContext* cx, JS::HandleString str) {
    5149          36 :         MOZ_ASSERT(!mBytes);
    5150          36 :         MOZ_ASSERT(cx);
    5151          36 :         mBytes = JS_EncodeStringToUTF8(cx, str);
    5152          36 :         return mBytes;
    5153             :     }
    5154             : 
    5155           0 :     void clear() {
    5156           0 :         js_free(mBytes);
    5157           0 :         mBytes = nullptr;
    5158           0 :     }
    5159             : 
    5160        6623 :     char* ptr() const {
    5161        6623 :         return mBytes;
    5162             :     }
    5163             : 
    5164        1619 :     bool operator!() const {
    5165        1619 :         return !mBytes;
    5166             :     }
    5167             : 
    5168           0 :     size_t length() const {
    5169           0 :         if (!mBytes)
    5170           0 :             return 0;
    5171           0 :         return strlen(mBytes);
    5172             :     }
    5173             : 
    5174             :   private:
    5175             :     char* mBytes;
    5176             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    5177             : 
    5178             :     /* Copy and assignment are not supported. */
    5179             :     JSAutoByteString(const JSAutoByteString& another);
    5180             :     JSAutoByteString& operator=(const JSAutoByteString& another);
    5181             : };
    5182             : 
    5183             : namespace JS {
    5184             : 
    5185             : extern JS_PUBLIC_API(JSAddonId*)
    5186             : NewAddonId(JSContext* cx, JS::HandleString str);
    5187             : 
    5188             : extern JS_PUBLIC_API(JSString*)
    5189             : StringOfAddonId(JSAddonId* id);
    5190             : 
    5191             : extern JS_PUBLIC_API(JSAddonId*)
    5192             : AddonIdOfObject(JSObject* obj);
    5193             : 
    5194             : } // namespace JS
    5195             : 
    5196             : /************************************************************************/
    5197             : /*
    5198             :  * Symbols
    5199             :  */
    5200             : 
    5201             : namespace JS {
    5202             : 
    5203             : /**
    5204             :  * Create a new Symbol with the given description. This function never returns
    5205             :  * a Symbol that is in the Runtime-wide symbol registry.
    5206             :  *
    5207             :  * If description is null, the new Symbol's [[Description]] attribute is
    5208             :  * undefined.
    5209             :  */
    5210             : JS_PUBLIC_API(Symbol*)
    5211             : NewSymbol(JSContext* cx, HandleString description);
    5212             : 
    5213             : /**
    5214             :  * Symbol.for as specified in ES6.
    5215             :  *
    5216             :  * Get a Symbol with the description 'key' from the Runtime-wide symbol registry.
    5217             :  * If there is not already a Symbol with that description in the registry, a new
    5218             :  * Symbol is created and registered. 'key' must not be null.
    5219             :  */
    5220             : JS_PUBLIC_API(Symbol*)
    5221             : GetSymbolFor(JSContext* cx, HandleString key);
    5222             : 
    5223             : /**
    5224             :  * Get the [[Description]] attribute of the given symbol.
    5225             :  *
    5226             :  * This function is infallible. If it returns null, that means the symbol's
    5227             :  * [[Description]] is undefined.
    5228             :  */
    5229             : JS_PUBLIC_API(JSString*)
    5230             : GetSymbolDescription(HandleSymbol symbol);
    5231             : 
    5232             : /* Well-known symbols. */
    5233             : #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
    5234             :     macro(isConcatSpreadable) \
    5235             :     macro(iterator) \
    5236             :     macro(match) \
    5237             :     macro(replace) \
    5238             :     macro(search) \
    5239             :     macro(species) \
    5240             :     macro(hasInstance) \
    5241             :     macro(split) \
    5242             :     macro(toPrimitive) \
    5243             :     macro(toStringTag) \
    5244             :     macro(unscopables) \
    5245             :     macro(asyncIterator)
    5246             : 
    5247             : enum class SymbolCode : uint32_t {
    5248             :     // There is one SymbolCode for each well-known symbol.
    5249             : #define JS_DEFINE_SYMBOL_ENUM(name) name,
    5250             :     JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM)  // SymbolCode::iterator, etc.
    5251             : #undef JS_DEFINE_SYMBOL_ENUM
    5252             :     Limit,
    5253             :     InSymbolRegistry = 0xfffffffe,  // created by Symbol.for() or JS::GetSymbolFor()
    5254             :     UniqueSymbol = 0xffffffff       // created by Symbol() or JS::NewSymbol()
    5255             : };
    5256             : 
    5257             : /* For use in loops that iterate over the well-known symbols. */
    5258             : const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
    5259             : 
    5260             : /**
    5261             :  * Return the SymbolCode telling what sort of symbol `symbol` is.
    5262             :  *
    5263             :  * A symbol's SymbolCode never changes once it is created.
    5264             :  */
    5265             : JS_PUBLIC_API(SymbolCode)
    5266             : GetSymbolCode(Handle<Symbol*> symbol);
    5267             : 
    5268             : /**
    5269             :  * Get one of the well-known symbols defined by ES6. A single set of well-known
    5270             :  * symbols is shared by all compartments in a JSRuntime.
    5271             :  *
    5272             :  * `which` must be in the range [0, WellKnownSymbolLimit).
    5273             :  */
    5274             : JS_PUBLIC_API(Symbol*)
    5275             : GetWellKnownSymbol(JSContext* cx, SymbolCode which);
    5276             : 
    5277             : /**
    5278             :  * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
    5279             :  * is actually a symbol code and not a string. See JS_SYM_FN.
    5280             :  */
    5281             : inline bool
    5282       62211 : PropertySpecNameIsSymbol(const char* name)
    5283             : {
    5284       62211 :     uintptr_t u = reinterpret_cast<uintptr_t>(name);
    5285       62211 :     return u != 0 && u - 1 < WellKnownSymbolLimit;
    5286             : }
    5287             : 
    5288             : JS_PUBLIC_API(bool)
    5289             : PropertySpecNameEqualsId(const char* name, HandleId id);
    5290             : 
    5291             : /**
    5292             :  * Create a jsid that does not need to be marked for GC.
    5293             :  *
    5294             :  * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
    5295             :  * resulting jsid, on success, is either an interned string or a well-known
    5296             :  * symbol; either way it is immune to GC so there is no need to visit *idp
    5297             :  * during GC marking.
    5298             :  */
    5299             : JS_PUBLIC_API(bool)
    5300             : PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp);
    5301             : 
    5302             : } /* namespace JS */
    5303             : 
    5304             : /************************************************************************/
    5305             : /*
    5306             :  * JSON functions
    5307             :  */
    5308             : typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data);
    5309             : 
    5310             : /**
    5311             :  * JSON.stringify as specified by ES5.
    5312             :  */
    5313             : JS_PUBLIC_API(bool)
    5314             : JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer,
    5315             :              JS::HandleValue space, JSONWriteCallback callback, void* data);
    5316             : 
    5317             : namespace JS {
    5318             : 
    5319             : /**
    5320             :  * An API akin to JS_Stringify but with the goal of not having observable
    5321             :  * side-effects when the stringification is performed.  This means it does not
    5322             :  * allow a replacer or a custom space, and has the following constraints on its
    5323             :  * input:
    5324             :  *
    5325             :  * 1) The input must be a plain object or array, not an abitrary value.
    5326             :  * 2) Every value in the graph reached by the algorithm starting with this
    5327             :  *    object must be one of the following: null, undefined, a string (NOT a
    5328             :  *    string object!), a boolean, a finite number (i.e. no NaN or Infinity or
    5329             :  *    -Infinity), a plain object with no accessor properties, or an Array with
    5330             :  *    no holes.
    5331             :  *
    5332             :  * The actual behavior differs from JS_Stringify only in asserting the above and
    5333             :  * NOT attempting to get the "toJSON" property from things, since that could
    5334             :  * clearly have side-effects.
    5335             :  */
    5336             : JS_PUBLIC_API(bool)
    5337             : ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input,
    5338             :                   JSONWriteCallback callback, void* data);
    5339             : 
    5340             : } /* namespace JS */
    5341             : 
    5342             : /**
    5343             :  * JSON.parse as specified by ES5.
    5344             :  */
    5345             : JS_PUBLIC_API(bool)
    5346             : JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp);
    5347             : 
    5348             : JS_PUBLIC_API(bool)
    5349             : JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp);
    5350             : 
    5351             : JS_PUBLIC_API(bool)
    5352             : JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver,
    5353             :                         JS::MutableHandleValue vp);
    5354             : 
    5355             : JS_PUBLIC_API(bool)
    5356             : JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver,
    5357             :                         JS::MutableHandleValue vp);
    5358             : 
    5359             : /************************************************************************/
    5360             : 
    5361             : /**
    5362             :  * The default locale for the ECMAScript Internationalization API
    5363             :  * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
    5364             :  * Note that the Internationalization API encourages clients to
    5365             :  * specify their own locales.
    5366             :  * The locale string remains owned by the caller.
    5367             :  */
    5368             : extern JS_PUBLIC_API(bool)
    5369             : JS_SetDefaultLocale(JSContext* cx, const char* locale);
    5370             : 
    5371             : /**
    5372             :  * Look up the default locale for the ECMAScript Internationalization API.
    5373             :  */
    5374             : extern JS_PUBLIC_API(JS::UniqueChars)
    5375             : JS_GetDefaultLocale(JSContext* cx);
    5376             : 
    5377             : /**
    5378             :  * Reset the default locale to OS defaults.
    5379             :  */
    5380             : extern JS_PUBLIC_API(void)
    5381             : JS_ResetDefaultLocale(JSContext* cx);
    5382             : 
    5383             : /**
    5384             :  * Locale specific string conversion and error message callbacks.
    5385             :  */
    5386           3 : struct JSLocaleCallbacks {
    5387             :     JSLocaleToUpperCase     localeToUpperCase; // not used #if EXPOSE_INTL_API
    5388             :     JSLocaleToLowerCase     localeToLowerCase; // not used #if EXPOSE_INTL_API
    5389             :     JSLocaleCompare         localeCompare; // not used #if EXPOSE_INTL_API
    5390             :     JSLocaleToUnicode       localeToUnicode;
    5391             : };
    5392             : 
    5393             : /**
    5394             :  * Establish locale callbacks. The pointer must persist as long as the
    5395             :  * JSContext.  Passing nullptr restores the default behaviour.
    5396             :  */
    5397             : extern JS_PUBLIC_API(void)
    5398             : JS_SetLocaleCallbacks(JSContext* cx, const JSLocaleCallbacks* callbacks);
    5399             : 
    5400             : /**
    5401             :  * Return the address of the current locale callbacks struct, which may
    5402             :  * be nullptr.
    5403             :  */
    5404             : extern JS_PUBLIC_API(const JSLocaleCallbacks*)
    5405             : JS_GetLocaleCallbacks(JSContext* cx);
    5406             : 
    5407             : /************************************************************************/
    5408             : 
    5409             : /*
    5410             :  * Error reporting.
    5411             :  */
    5412             : 
    5413             : namespace JS {
    5414             : const uint16_t MaxNumErrorArguments = 10;
    5415             : };
    5416             : 
    5417             : /**
    5418             :  * Report an exception represented by the sprintf-like conversion of format
    5419             :  * and its arguments.
    5420             :  */
    5421             : extern JS_PUBLIC_API(void)
    5422             : JS_ReportErrorASCII(JSContext* cx, const char* format, ...)
    5423             :     MOZ_FORMAT_PRINTF(2, 3);
    5424             : 
    5425             : extern JS_PUBLIC_API(void)
    5426             : JS_ReportErrorLatin1(JSContext* cx, const char* format, ...)
    5427             :     MOZ_FORMAT_PRINTF(2, 3);
    5428             : 
    5429             : extern JS_PUBLIC_API(void)
    5430             : JS_ReportErrorUTF8(JSContext* cx, const char* format, ...)
    5431             :     MOZ_FORMAT_PRINTF(2, 3);
    5432             : 
    5433             : /*
    5434             :  * Use an errorNumber to retrieve the format string, args are char*
    5435             :  */
    5436             : extern JS_PUBLIC_API(void)
    5437             : JS_ReportErrorNumberASCII(JSContext* cx, JSErrorCallback errorCallback,
    5438             :                           void* userRef, const unsigned errorNumber, ...);
    5439             : 
    5440             : extern JS_PUBLIC_API(void)
    5441             : JS_ReportErrorNumberASCIIVA(JSContext* cx, JSErrorCallback errorCallback,
    5442             :                             void* userRef, const unsigned errorNumber, va_list ap);
    5443             : 
    5444             : extern JS_PUBLIC_API(void)
    5445             : JS_ReportErrorNumberLatin1(JSContext* cx, JSErrorCallback errorCallback,
    5446             :                            void* userRef, const unsigned errorNumber, ...);
    5447             : 
    5448             : #ifdef va_start
    5449             : extern JS_PUBLIC_API(void)
    5450             : JS_ReportErrorNumberLatin1VA(JSContext* cx, JSErrorCallback errorCallback,
    5451             :                              void* userRef, const unsigned errorNumber, va_list ap);
    5452             : #endif
    5453             : 
    5454             : extern JS_PUBLIC_API(void)
    5455             : JS_ReportErrorNumberUTF8(JSContext* cx, JSErrorCallback errorCallback,
    5456             :                            void* userRef, const unsigned errorNumber, ...);
    5457             : 
    5458             : #ifdef va_start
    5459             : extern JS_PUBLIC_API(void)
    5460             : JS_ReportErrorNumberUTF8VA(JSContext* cx, JSErrorCallback errorCallback,
    5461             :                            void* userRef, const unsigned errorNumber, va_list ap);
    5462             : #endif
    5463             : 
    5464             : /*
    5465             :  * Use an errorNumber to retrieve the format string, args are char16_t*
    5466             :  */
    5467             : extern JS_PUBLIC_API(void)
    5468             : JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback,
    5469             :                      void* userRef, const unsigned errorNumber, ...);
    5470             : 
    5471             : extern JS_PUBLIC_API(void)
    5472             : JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback,
    5473             :                             void* userRef, const unsigned errorNumber,
    5474             :                             const char16_t** args);
    5475             : 
    5476             : /**
    5477             :  * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
    5478             :  * Return true if there was no error trying to issue the warning, and if the
    5479             :  * warning was not converted into an error due to the JSOPTION_WERROR option
    5480             :  * being set, false otherwise.
    5481             :  */
    5482             : extern JS_PUBLIC_API(bool)
    5483             : JS_ReportWarningASCII(JSContext* cx, const char* format, ...)
    5484             :     MOZ_FORMAT_PRINTF(2, 3);
    5485             : 
    5486             : extern JS_PUBLIC_API(bool)
    5487             : JS_ReportWarningLatin1(JSContext* cx, const char* format, ...)
    5488             :     MOZ_FORMAT_PRINTF(2, 3);
    5489             : 
    5490             : extern JS_PUBLIC_API(bool)
    5491             : JS_ReportWarningUTF8(JSContext* cx, const char* format, ...)
    5492             :     MOZ_FORMAT_PRINTF(2, 3);
    5493             : 
    5494             : extern JS_PUBLIC_API(bool)
    5495             : JS_ReportErrorFlagsAndNumberASCII(JSContext* cx, unsigned flags,
    5496             :                                   JSErrorCallback errorCallback, void* userRef,
    5497             :                                   const unsigned errorNumber, ...);
    5498             : 
    5499             : extern JS_PUBLIC_API(bool)
    5500             : JS_ReportErrorFlagsAndNumberLatin1(JSContext* cx, unsigned flags,
    5501             :                                    JSErrorCallback errorCallback, void* userRef,
    5502             :                                    const unsigned errorNumber, ...);
    5503             : 
    5504             : extern JS_PUBLIC_API(bool)
    5505             : JS_ReportErrorFlagsAndNumberUTF8(JSContext* cx, unsigned flags,
    5506             :                                  JSErrorCallback errorCallback, void* userRef,
    5507             :                                  const unsigned errorNumber, ...);
    5508             : 
    5509             : extern JS_PUBLIC_API(bool)
    5510             : JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags,
    5511             :                                JSErrorCallback errorCallback, void* userRef,
    5512             :                                const unsigned errorNumber, ...);
    5513             : 
    5514             : /**
    5515             :  * Complain when out of memory.
    5516             :  */
    5517             : extern JS_PUBLIC_API(void)
    5518             : JS_ReportOutOfMemory(JSContext* cx);
    5519             : 
    5520             : /**
    5521             :  * Complain when an allocation size overflows the maximum supported limit.
    5522             :  */
    5523             : extern JS_PUBLIC_API(void)
    5524             : JS_ReportAllocationOverflow(JSContext* cx);
    5525             : 
    5526             : /**
    5527             :  * Base class that implements parts shared by JSErrorReport and
    5528             :  * JSErrorNotes::Note.
    5529             :  */
    5530             : class JSErrorBase
    5531             : {
    5532             :     // The (default) error message.
    5533             :     // If ownsMessage_ is true, the it is freed in destructor.
    5534             :     JS::ConstUTF8CharsZ message_;
    5535             : 
    5536             :   public:
    5537           4 :     JSErrorBase()
    5538           4 :       : filename(nullptr), lineno(0), column(0),
    5539             :         errorNumber(0),
    5540           4 :         ownsMessage_(false)
    5541           4 :     {}
    5542             : 
    5543           4 :     ~JSErrorBase() {
    5544           2 :         freeMessage();
    5545           2 :     }
    5546             : 
    5547             :     // Source file name, URL, etc., or null.
    5548             :     const char* filename;
    5549             : 
    5550             :     // Source line number.
    5551             :     unsigned lineno;
    5552             : 
    5553             :     // Zero-based column index in line.
    5554             :     unsigned column;
    5555             : 
    5556             :     // the error number, e.g. see js.msg.
    5557             :     unsigned errorNumber;
    5558             : 
    5559             :   private:
    5560             :     bool ownsMessage_ : 1;
    5561             : 
    5562             :   public:
    5563          10 :     const JS::ConstUTF8CharsZ message() const {
    5564          10 :         return message_;
    5565             :     }
    5566             : 
    5567           2 :     void initOwnedMessage(const char* messageArg) {
    5568           2 :         initBorrowedMessage(messageArg);
    5569           2 :         ownsMessage_ = true;
    5570           2 :     }
    5571           4 :     void initBorrowedMessage(const char* messageArg) {
    5572           4 :         MOZ_ASSERT(!message_);
    5573           4 :         message_ = JS::ConstUTF8CharsZ(messageArg, strlen(messageArg));
    5574           4 :     }
    5575             : 
    5576             :     JSString* newMessageString(JSContext* cx);
    5577             : 
    5578             :   private:
    5579             :     void freeMessage();
    5580             : };
    5581             : 
    5582             : /**
    5583             :  * Notes associated with JSErrorReport.
    5584             :  */
    5585             : class JSErrorNotes
    5586             : {
    5587             :   public:
    5588           0 :     class Note : public JSErrorBase
    5589             :     {};
    5590             : 
    5591             :   private:
    5592             :     // Stores pointers to each note.
    5593             :     js::Vector<js::UniquePtr<Note>, 1, js::SystemAllocPolicy> notes_;
    5594             : 
    5595             :   public:
    5596             :     JSErrorNotes();
    5597             :     ~JSErrorNotes();
    5598             : 
    5599             :     // Add an note to the given position.
    5600             :     bool addNoteASCII(JSContext* cx,
    5601             :                       const char* filename, unsigned lineno, unsigned column,
    5602             :                       JSErrorCallback errorCallback, void* userRef,
    5603             :                       const unsigned errorNumber, ...);
    5604             :     bool addNoteLatin1(JSContext* cx,
    5605             :                        const char* filename, unsigned lineno, unsigned column,
    5606             :                        JSErrorCallback errorCallback, void* userRef,
    5607             :                        const unsigned errorNumber, ...);
    5608             :     bool addNoteUTF8(JSContext* cx,
    5609             :                      const char* filename, unsigned lineno, unsigned column,
    5610             :                      JSErrorCallback errorCallback, void* userRef,
    5611             :                      const unsigned errorNumber, ...);
    5612             : 
    5613             :     JS_PUBLIC_API(size_t) length();
    5614             : 
    5615             :     // Create a deep copy of notes.
    5616             :     js::UniquePtr<JSErrorNotes> copy(JSContext* cx);
    5617             : 
    5618             :     class iterator : public std::iterator<std::input_iterator_tag, js::UniquePtr<Note>>
    5619             :     {
    5620             :         js::UniquePtr<Note>* note_;
    5621             :       public:
    5622           0 :         explicit iterator(js::UniquePtr<Note>* note = nullptr) : note_(note)
    5623           0 :         {}
    5624             : 
    5625           0 :         bool operator==(iterator other) const {
    5626           0 :             return note_ == other.note_;
    5627             :         }
    5628           0 :         bool operator!=(iterator other) const {
    5629           0 :             return !(*this == other);
    5630             :         }
    5631           0 :         iterator& operator++() {
    5632           0 :             note_++;
    5633           0 :             return *this;
    5634             :         }
    5635           0 :         reference operator*() {
    5636           0 :             return *note_;
    5637             :         }
    5638             :     };
    5639             :     JS_PUBLIC_API(iterator) begin();
    5640             :     JS_PUBLIC_API(iterator) end();
    5641             : };
    5642             : 
    5643             : /**
    5644             :  * Describes a single error or warning that occurs in the execution of script.
    5645             :  */
    5646             : class JSErrorReport : public JSErrorBase
    5647             : {
    5648             :     // Offending source line without final '\n'.
    5649             :     // If ownsLinebuf_ is true, the buffer is freed in destructor.
    5650             :     const char16_t* linebuf_;
    5651             : 
    5652             :     // Number of chars in linebuf_. Does not include trailing '\0'.
    5653             :     size_t linebufLength_;
    5654             : 
    5655             :     // The 0-based offset of error token in linebuf_.
    5656             :     size_t tokenOffset_;
    5657             : 
    5658             :   public:
    5659           4 :     JSErrorReport()
    5660           4 :       : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
    5661             :         notes(nullptr),
    5662             :         flags(0), exnType(0), isMuted(false),
    5663           4 :         ownsLinebuf_(false)
    5664           4 :     {}
    5665             : 
    5666           4 :     ~JSErrorReport() {
    5667           2 :         freeLinebuf();
    5668           2 :     }
    5669             : 
    5670             :     // Associated notes, or nullptr if there's no note.
    5671             :     js::UniquePtr<JSErrorNotes> notes;
    5672             : 
    5673             :     // error/warning, etc.
    5674             :     unsigned flags;
    5675             : 
    5676             :     // One of the JSExnType constants.
    5677             :     int16_t exnType;
    5678             : 
    5679             :     // See the comment in TransitiveCompileOptions.
    5680             :     bool isMuted : 1;
    5681             : 
    5682             :   private:
    5683             :     bool ownsLinebuf_ : 1;
    5684             : 
    5685             :   public:
    5686           4 :     const char16_t* linebuf() const {
    5687           4 :         return linebuf_;
    5688             :     }
    5689           0 :     size_t linebufLength() const {
    5690           0 :         return linebufLength_;
    5691             :     }
    5692           0 :     size_t tokenOffset() const {
    5693           0 :         return tokenOffset_;
    5694             :     }
    5695           0 :     void initOwnedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg,
    5696             :                           size_t tokenOffsetArg) {
    5697           0 :         initBorrowedLinebuf(linebufArg, linebufLengthArg, tokenOffsetArg);
    5698           0 :         ownsLinebuf_ = true;
    5699           0 :     }
    5700             :     void initBorrowedLinebuf(const char16_t* linebufArg, size_t linebufLengthArg,
    5701             :                              size_t tokenOffsetArg);
    5702             : 
    5703             :   private:
    5704             :     void freeLinebuf();
    5705             : };
    5706             : 
    5707             : /*
    5708             :  * JSErrorReport flag values.  These may be freely composed.
    5709             :  */
    5710             : #define JSREPORT_ERROR      0x0     /* pseudo-flag for default case */
    5711             : #define JSREPORT_WARNING    0x1     /* reported via JS_ReportWarning */
    5712             : #define JSREPORT_EXCEPTION  0x2     /* exception was thrown */
    5713             : #define JSREPORT_STRICT     0x4     /* error or warning due to strict option */
    5714             : 
    5715             : #define JSREPORT_USER_1     0x8     /* user-defined flag */
    5716             : 
    5717             : /*
    5718             :  * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
    5719             :  * has been thrown for this runtime error, and the host should ignore it.
    5720             :  * Exception-aware hosts should also check for JS_IsExceptionPending if
    5721             :  * JS_ExecuteScript returns failure, and signal or propagate the exception, as
    5722             :  * appropriate.
    5723             :  */
    5724             : #define JSREPORT_IS_WARNING(flags)      (((flags) & JSREPORT_WARNING) != 0)
    5725             : #define JSREPORT_IS_EXCEPTION(flags)    (((flags) & JSREPORT_EXCEPTION) != 0)
    5726             : #define JSREPORT_IS_STRICT(flags)       (((flags) & JSREPORT_STRICT) != 0)
    5727             : 
    5728             : namespace JS {
    5729             : 
    5730             : using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report);
    5731             : 
    5732             : extern JS_PUBLIC_API(WarningReporter)
    5733             : SetWarningReporter(JSContext* cx, WarningReporter reporter);
    5734             : 
    5735             : extern JS_PUBLIC_API(WarningReporter)
    5736             : GetWarningReporter(JSContext* cx);
    5737             : 
    5738             : extern JS_PUBLIC_API(bool)
    5739             : CreateError(JSContext* cx, JSExnType type, HandleObject stack,
    5740             :             HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
    5741             :             JSErrorReport* report, HandleString message, MutableHandleValue rval);
    5742             : 
    5743             : /************************************************************************/
    5744             : 
    5745             : /*
    5746             :  * Weak Maps.
    5747             :  */
    5748             : 
    5749             : extern JS_PUBLIC_API(JSObject*)
    5750             : NewWeakMapObject(JSContext* cx);
    5751             : 
    5752             : extern JS_PUBLIC_API(bool)
    5753             : IsWeakMapObject(JSObject* obj);
    5754             : 
    5755             : extern JS_PUBLIC_API(bool)
    5756             : GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
    5757             :                 JS::MutableHandleValue val);
    5758             : 
    5759             : extern JS_PUBLIC_API(bool)
    5760             : SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
    5761             :                 JS::HandleValue val);
    5762             : 
    5763             : /*
    5764             :  * Map
    5765             :  */
    5766             : extern JS_PUBLIC_API(JSObject*)
    5767             : NewMapObject(JSContext* cx);
    5768             : 
    5769             : extern JS_PUBLIC_API(uint32_t)
    5770             : MapSize(JSContext* cx, HandleObject obj);
    5771             : 
    5772             : extern JS_PUBLIC_API(bool)
    5773             : MapGet(JSContext* cx, HandleObject obj,
    5774             :        HandleValue key, MutableHandleValue rval);
    5775             : 
    5776             : extern JS_PUBLIC_API(bool)
    5777             : MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
    5778             : 
    5779             : extern JS_PUBLIC_API(bool)
    5780             : MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val);
    5781             : 
    5782             : extern JS_PUBLIC_API(bool)
    5783             : MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
    5784             : 
    5785             : extern JS_PUBLIC_API(bool)
    5786             : MapClear(JSContext* cx, HandleObject obj);
    5787             : 
    5788             : extern JS_PUBLIC_API(bool)
    5789             : MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval);
    5790             : 
    5791             : extern JS_PUBLIC_API(bool)
    5792             : MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval);
    5793             : 
    5794             : extern JS_PUBLIC_API(bool)
    5795             : MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval);
    5796             : 
    5797             : extern JS_PUBLIC_API(bool)
    5798             : MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
    5799             : 
    5800             : /*
    5801             :  * Set
    5802             :  */
    5803             : extern JS_PUBLIC_API(JSObject *)
    5804             : NewSetObject(JSContext *cx);
    5805             : 
    5806             : extern JS_PUBLIC_API(uint32_t)
    5807             : SetSize(JSContext *cx, HandleObject obj);
    5808             : 
    5809             : extern JS_PUBLIC_API(bool)
    5810             : SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
    5811             : 
    5812             : extern JS_PUBLIC_API(bool)
    5813             : SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
    5814             : 
    5815             : extern JS_PUBLIC_API(bool)
    5816             : SetAdd(JSContext *cx, HandleObject obj, HandleValue key);
    5817             : 
    5818             : extern JS_PUBLIC_API(bool)
    5819             : SetClear(JSContext *cx, HandleObject obj);
    5820             : 
    5821             : extern JS_PUBLIC_API(bool)
    5822             : SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval);
    5823             : 
    5824             : extern JS_PUBLIC_API(bool)
    5825             : SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval);
    5826             : 
    5827             : extern JS_PUBLIC_API(bool)
    5828             : SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval);
    5829             : 
    5830             : extern JS_PUBLIC_API(bool)
    5831             : SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
    5832             : 
    5833             : } /* namespace JS */
    5834             : 
    5835             : /*
    5836             :  * Dates.
    5837             :  */
    5838             : 
    5839             : extern JS_PUBLIC_API(JSObject*)
    5840             : JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec);
    5841             : 
    5842             : /**
    5843             :  * Returns true and sets |*isDate| indicating whether |obj| is a Date object or
    5844             :  * a wrapper around one, otherwise returns false on failure.
    5845             :  *
    5846             :  * This method returns true with |*isDate == false| when passed a proxy whose
    5847             :  * target is a Date, or when passed a revoked proxy.
    5848             :  */
    5849             : extern JS_PUBLIC_API(bool)
    5850             : JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
    5851             : 
    5852             : /************************************************************************/
    5853             : 
    5854             : /*
    5855             :  * Regular Expressions.
    5856             :  */
    5857             : #define JSREG_FOLD      0x01u   /* fold uppercase to lowercase */
    5858             : #define JSREG_GLOB      0x02u   /* global exec, creates array of matches */
    5859             : #define JSREG_MULTILINE 0x04u   /* treat ^ and $ as begin and end of line */
    5860             : #define JSREG_STICKY    0x08u   /* only match starting at lastIndex */
    5861             : #define JSREG_UNICODE   0x10u   /* unicode */
    5862             : 
    5863             : extern JS_PUBLIC_API(JSObject*)
    5864             : JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
    5865             : 
    5866             : extern JS_PUBLIC_API(JSObject*)
    5867             : JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags);
    5868             : 
    5869             : extern JS_PUBLIC_API(bool)
    5870             : JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input);
    5871             : 
    5872             : extern JS_PUBLIC_API(bool)
    5873             : JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj);
    5874             : 
    5875             : extern JS_PUBLIC_API(bool)
    5876             : JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj,
    5877             :                  char16_t* chars, size_t length, size_t* indexp, bool test,
    5878             :                  JS::MutableHandleValue rval);
    5879             : 
    5880             : /* RegExp interface for clients without a global object. */
    5881             : 
    5882             : extern JS_PUBLIC_API(bool)
    5883             : JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length,
    5884             :                           size_t* indexp, bool test, JS::MutableHandleValue rval);
    5885             : 
    5886             : /**
    5887             :  * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp
    5888             :  * object or a wrapper around one, otherwise returns false on failure.
    5889             :  *
    5890             :  * This method returns true with |*isRegExp == false| when passed a proxy whose
    5891             :  * target is a RegExp, or when passed a revoked proxy.
    5892             :  */
    5893             : extern JS_PUBLIC_API(bool)
    5894             : JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp);
    5895             : 
    5896             : extern JS_PUBLIC_API(unsigned)
    5897             : JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj);
    5898             : 
    5899             : extern JS_PUBLIC_API(JSString*)
    5900             : JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj);
    5901             : 
    5902             : /************************************************************************/
    5903             : 
    5904             : extern JS_PUBLIC_API(bool)
    5905             : JS_IsExceptionPending(JSContext* cx);
    5906             : 
    5907             : extern JS_PUBLIC_API(bool)
    5908             : JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
    5909             : 
    5910             : extern JS_PUBLIC_API(void)
    5911             : JS_SetPendingException(JSContext* cx, JS::HandleValue v);
    5912             : 
    5913             : extern JS_PUBLIC_API(void)
    5914             : JS_ClearPendingException(JSContext* cx);
    5915             : 
    5916             : namespace JS {
    5917             : 
    5918             : /**
    5919             :  * Save and later restore the current exception state of a given JSContext.
    5920             :  * This is useful for implementing behavior in C++ that's like try/catch
    5921             :  * or try/finally in JS.
    5922             :  *
    5923             :  * Typical usage:
    5924             :  *
    5925             :  *     bool ok = JS::Evaluate(cx, ...);
    5926             :  *     AutoSaveExceptionState savedExc(cx);
    5927             :  *     ... cleanup that might re-enter JS ...
    5928             :  *     return ok;
    5929             :  */
    5930             : class JS_PUBLIC_API(AutoSaveExceptionState)
    5931             : {
    5932             :   private:
    5933             :     JSContext* context;
    5934             :     bool wasPropagatingForcedReturn;
    5935             :     bool wasOverRecursed;
    5936             :     bool wasThrowing;
    5937             :     RootedValue exceptionValue;
    5938             : 
    5939             :   public:
    5940             :     /*
    5941             :      * Take a snapshot of cx's current exception state. Then clear any current
    5942             :      * pending exception in cx.
    5943             :      */
    5944             :     explicit AutoSaveExceptionState(JSContext* cx);
    5945             : 
    5946             :     /*
    5947             :      * If neither drop() nor restore() was called, restore the exception
    5948             :      * state only if no exception is currently pending on cx.
    5949             :      */
    5950             :     ~AutoSaveExceptionState();
    5951             : 
    5952             :     /*
    5953             :      * Discard any stored exception state.
    5954             :      * If this is called, the destructor is a no-op.
    5955             :      */
    5956        2330 :     void drop() {
    5957        2330 :         wasPropagatingForcedReturn = false;
    5958        2330 :         wasOverRecursed = false;
    5959        2330 :         wasThrowing = false;
    5960        2330 :         exceptionValue.setUndefined();
    5961        2330 :     }
    5962             : 
    5963             :     /*
    5964             :      * Replace cx's exception state with the stored exception state. Then
    5965             :      * discard the stored exception state. If this is called, the
    5966             :      * destructor is a no-op.
    5967             :      */
    5968             :     void restore();
    5969             : };
    5970             : 
    5971             : } /* namespace JS */
    5972             : 
    5973             : /* Deprecated API. Use AutoSaveExceptionState instead. */
    5974             : extern JS_PUBLIC_API(JSExceptionState*)
    5975             : JS_SaveExceptionState(JSContext* cx);
    5976             : 
    5977             : extern JS_PUBLIC_API(void)
    5978             : JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state);
    5979             : 
    5980             : extern JS_PUBLIC_API(void)
    5981             : JS_DropExceptionState(JSContext* cx, JSExceptionState* state);
    5982             : 
    5983             : /**
    5984             :  * If the given object is an exception object, the exception will have (or be
    5985             :  * able to lazily create) an error report struct, and this function will return
    5986             :  * the address of that struct.  Otherwise, it returns nullptr. The lifetime
    5987             :  * of the error report struct that might be returned is the same as the
    5988             :  * lifetime of the exception object.
    5989             :  */
    5990             : extern JS_PUBLIC_API(JSErrorReport*)
    5991             : JS_ErrorFromException(JSContext* cx, JS::HandleObject obj);
    5992             : 
    5993             : /**
    5994             :  * If the given object is an exception object (or an unwrappable
    5995             :  * cross-compartment wrapper for one), return the stack for that exception, if
    5996             :  * any.  Will return null if the given object is not an exception object
    5997             :  * (including if it's null or a security wrapper that can't be unwrapped) or if
    5998             :  * the exception has no stack.
    5999             :  */
    6000             : extern JS_PUBLIC_API(JSObject*)
    6001             : ExceptionStackOrNull(JS::HandleObject obj);
    6002             : 
    6003             : /*
    6004             :  * Throws a StopIteration exception on cx.
    6005             :  */
    6006             : extern JS_PUBLIC_API(bool)
    6007             : JS_ThrowStopIteration(JSContext* cx);
    6008             : 
    6009             : extern JS_PUBLIC_API(bool)
    6010             : JS_IsStopIteration(const JS::Value& v);
    6011             : 
    6012             : /**
    6013             :  * A JS context always has an "owner thread". The owner thread is set when the
    6014             :  * context is created (to the current thread) and practically all entry points
    6015             :  * into the JS engine check that a context (or anything contained in the
    6016             :  * context: runtime, compartment, object, etc) is only touched by its owner
    6017             :  * thread. Embeddings may check this invariant outside the JS engine by calling
    6018             :  * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
    6019             :  * non-debug builds).
    6020             :  */
    6021             : 
    6022             : extern JS_PUBLIC_API(void)
    6023             : JS_AbortIfWrongThread(JSContext* cx);
    6024             : 
    6025             : /************************************************************************/
    6026             : 
    6027             : /**
    6028             :  * A constructor can request that the JS engine create a default new 'this'
    6029             :  * object of the given class, using the callee to determine parentage and
    6030             :  * [[Prototype]].
    6031             :  */
    6032             : extern JS_PUBLIC_API(JSObject*)
    6033             : JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
    6034             : 
    6035             : /************************************************************************/
    6036             : 
    6037             : #ifdef JS_GC_ZEAL
    6038             : #define JS_DEFAULT_ZEAL_FREQ 100
    6039             : 
    6040             : extern JS_PUBLIC_API(void)
    6041             : JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
    6042             : 
    6043             : extern JS_PUBLIC_API(void)
    6044             : JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency);
    6045             : 
    6046             : extern JS_PUBLIC_API(void)
    6047             : JS_ScheduleGC(JSContext* cx, uint32_t count);
    6048             : #endif
    6049             : 
    6050             : extern JS_PUBLIC_API(void)
    6051             : JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
    6052             : 
    6053             : extern JS_PUBLIC_API(void)
    6054             : JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
    6055             : 
    6056             : #define JIT_COMPILER_OPTIONS(Register)                                      \
    6057             :     Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger")            \
    6058             :     Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger")                      \
    6059             :     Register(ION_GVN_ENABLE, "ion.gvn.enable")                              \
    6060             :     Register(ION_FORCE_IC, "ion.forceinlineCaches")                         \
    6061             :     Register(ION_ENABLE, "ion.enable")                                      \
    6062             :     Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
    6063             :     Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis")          \
    6064             :     Register(BASELINE_ENABLE, "baseline.enable")                            \
    6065             :     Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable")  \
    6066             :     Register(FULL_DEBUG_CHECKS, "jit.full-debug-checks")                    \
    6067             :     Register(JUMP_THRESHOLD, "jump-threshold")                              \
    6068             :     Register(SIMULATOR_ALWAYS_INTERRUPT, "simulator.always-interrupt")      \
    6069             :     Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable")                  \
    6070             :     Register(WASM_TEST_MODE, "wasm.test-mode")                              \
    6071             :     Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
    6072             : 
    6073             : typedef enum JSJitCompilerOption {
    6074             : #define JIT_COMPILER_DECLARE(key, str) \
    6075             :     JSJITCOMPILER_ ## key,
    6076             : 
    6077             :     JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
    6078             : #undef JIT_COMPILER_DECLARE
    6079             : 
    6080             :     JSJITCOMPILER_NOT_AN_OPTION
    6081             : } JSJitCompilerOption;
    6082             : 
    6083             : extern JS_PUBLIC_API(void)
    6084             : JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t value);
    6085             : extern JS_PUBLIC_API(bool)
    6086             : JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t* valueOut);
    6087             : 
    6088             : /**
    6089             :  * Convert a uint32_t index into a jsid.
    6090             :  */
    6091             : extern JS_PUBLIC_API(bool)
    6092             : JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId);
    6093             : 
    6094             : /**
    6095             :  * Convert chars into a jsid.
    6096             :  *
    6097             :  * |chars| may not be an index.
    6098             :  */
    6099             : extern JS_PUBLIC_API(bool)
    6100             : JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
    6101             : 
    6102             : /**
    6103             :  *  Test if the given string is a valid ECMAScript identifier
    6104             :  */
    6105             : extern JS_PUBLIC_API(bool)
    6106             : JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier);
    6107             : 
    6108             : /**
    6109             :  * Test whether the given chars + length are a valid ECMAScript identifier.
    6110             :  * This version is infallible, so just returns whether the chars are an
    6111             :  * identifier.
    6112             :  */
    6113             : extern JS_PUBLIC_API(bool)
    6114             : JS_IsIdentifier(const char16_t* chars, size_t length);
    6115             : 
    6116             : namespace js {
    6117             : class ScriptSource;
    6118             : } // namespace js
    6119             : 
    6120             : namespace JS {
    6121             : 
    6122             : class MOZ_RAII JS_PUBLIC_API(AutoFilename)
    6123             : {
    6124             :   private:
    6125             :     js::ScriptSource* ss_;
    6126             :     mozilla::Variant<const char*, UniqueChars> filename_;
    6127             : 
    6128             :     AutoFilename(const AutoFilename&) = delete;
    6129             :     AutoFilename& operator=(const AutoFilename&) = delete;
    6130             : 
    6131             :   public:
    6132          47 :     AutoFilename()
    6133          47 :       : ss_(nullptr),
    6134          47 :         filename_(mozilla::AsVariant<const char*>(nullptr))
    6135          47 :     {}
    6136             : 
    6137          94 :     ~AutoFilename() {
    6138          47 :         reset();
    6139          47 :     }
    6140             : 
    6141             :     void reset();
    6142             : 
    6143             :     void setOwned(UniqueChars&& filename);
    6144             :     void setUnowned(const char* filename);
    6145             :     void setScriptSource(js::ScriptSource* ss);
    6146             : 
    6147             :     const char* get() const;
    6148             : };
    6149             : 
    6150             : /**
    6151             :  * Return the current filename, line number and column number of the most
    6152             :  * currently running frame. Returns true if a scripted frame was found, false
    6153             :  * otherwise.
    6154             :  *
    6155             :  * If a the embedding has hidden the scripted caller for the topmost activation
    6156             :  * record, this will also return false.
    6157             :  */
    6158             : extern JS_PUBLIC_API(bool)
    6159             : DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr,
    6160             :                        unsigned* lineno = nullptr, unsigned* column = nullptr);
    6161             : 
    6162             : extern JS_PUBLIC_API(JSObject*)
    6163             : GetScriptedCallerGlobal(JSContext* cx);
    6164             : 
    6165             : /**
    6166             :  * Informs the JS engine that the scripted caller should be hidden. This can be
    6167             :  * used by the embedding to maintain an override of the scripted caller in its
    6168             :  * calculations, by hiding the scripted caller in the JS engine and pushing data
    6169             :  * onto a separate stack, which it inspects when DescribeScriptedCaller returns
    6170             :  * null.
    6171             :  *
    6172             :  * We maintain a counter on each activation record. Add() increments the counter
    6173             :  * of the topmost activation, and Remove() decrements it. The count may never
    6174             :  * drop below zero, and must always be exactly zero when the activation is
    6175             :  * popped from the stack.
    6176             :  */
    6177             : extern JS_PUBLIC_API(void)
    6178             : HideScriptedCaller(JSContext* cx);
    6179             : 
    6180             : extern JS_PUBLIC_API(void)
    6181             : UnhideScriptedCaller(JSContext* cx);
    6182             : 
    6183             : class MOZ_RAII AutoHideScriptedCaller
    6184             : {
    6185             :   public:
    6186        4136 :     explicit AutoHideScriptedCaller(JSContext* cx
    6187             :                                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
    6188        4136 :       : mContext(cx)
    6189             :     {
    6190        4136 :         MOZ_GUARD_OBJECT_NOTIFIER_INIT;
    6191        4136 :         HideScriptedCaller(mContext);
    6192        4136 :     }
    6193        8258 :     ~AutoHideScriptedCaller() {
    6194        4129 :         UnhideScriptedCaller(mContext);
    6195        4129 :     }
    6196             : 
    6197             :   protected:
    6198             :     JSContext* mContext;
    6199             :     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
    6200             : };
    6201             : 
    6202             : /*
    6203             :  * Encode/Decode interpreted scripts and functions to/from memory.
    6204             :  */
    6205             : 
    6206             : typedef mozilla::Vector<uint8_t> TranscodeBuffer;
    6207             : typedef mozilla::Range<uint8_t> TranscodeRange;
    6208             : 
    6209             : struct TranscodeSource
    6210             : {
    6211         187 :     TranscodeSource(const TranscodeRange& range_, const char* file, uint32_t line)
    6212         187 :         : range(range_), filename(file), lineno(line)
    6213         187 :     {}
    6214             : 
    6215             :     const TranscodeRange range;
    6216             :     const char* filename;
    6217             :     const uint32_t lineno;
    6218             : };
    6219             : 
    6220             : typedef mozilla::Vector<JS::TranscodeSource> TranscodeSources;
    6221             : 
    6222             : enum TranscodeResult
    6223             : {
    6224             :     // Successful encoding / decoding.
    6225             :     TranscodeResult_Ok = 0,
    6226             : 
    6227             :     // A warning message, is set to the message out-param.
    6228             :     TranscodeResult_Failure = 0x100,
    6229             :     TranscodeResult_Failure_BadBuildId =          TranscodeResult_Failure | 0x1,
    6230             :     TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2,
    6231             :     TranscodeResult_Failure_AsmJSNotSupported =   TranscodeResult_Failure | 0x3,
    6232             :     TranscodeResult_Failure_UnknownClassKind =    TranscodeResult_Failure | 0x4,
    6233             :     TranscodeResult_Failure_WrongCompileOption =  TranscodeResult_Failure | 0x5,
    6234             :     TranscodeResult_Failure_NotInterpretedFun =   TranscodeResult_Failure | 0x6,
    6235             : 
    6236             :     // There is a pending exception on the context.
    6237             :     TranscodeResult_Throw = 0x200
    6238             : };
    6239             : 
    6240             : extern JS_PUBLIC_API(TranscodeResult)
    6241             : EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script);
    6242             : 
    6243             : extern JS_PUBLIC_API(TranscodeResult)
    6244             : EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj);
    6245             : 
    6246             : extern JS_PUBLIC_API(TranscodeResult)
    6247             : DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp,
    6248             :              size_t cursorIndex = 0);
    6249             : 
    6250             : extern JS_PUBLIC_API(TranscodeResult)
    6251             : DecodeScript(JSContext* cx, const TranscodeRange& range, JS::MutableHandleScript scriptp);
    6252             : 
    6253             : extern JS_PUBLIC_API(TranscodeResult)
    6254             : DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp,
    6255             :                           size_t cursorIndex = 0);
    6256             : 
    6257             : // Register an encoder on the given script source, such that all functions can
    6258             : // be encoded as they are parsed. This strategy is used to avoid blocking the
    6259             : // active thread in a non-interruptible way.
    6260             : //
    6261             : // The |script| argument of |StartIncrementalEncoding| and
    6262             : // |FinishIncrementalEncoding| should be the top-level script returned either as
    6263             : // an out-param of any of the |Compile| functions, or the result of
    6264             : // |FinishOffThreadScript|.
    6265             : //
    6266             : // The |buffer| argument of |FinishIncrementalEncoding| is used for appending
    6267             : // the encoded bytecode into the buffer. If any of these functions failed, the
    6268             : // content of |buffer| would be undefined.
    6269             : extern JS_PUBLIC_API(bool)
    6270             : StartIncrementalEncoding(JSContext* cx, JS::HandleScript script);
    6271             : 
    6272             : extern JS_PUBLIC_API(bool)
    6273             : FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer);
    6274             : 
    6275             : } /* namespace JS */
    6276             : 
    6277             : namespace js {
    6278             : 
    6279             : enum class StackFormat { SpiderMonkey, V8, Default };
    6280             : 
    6281             : /*
    6282             :  * Sets the format used for stringifying Error stacks.
    6283             :  *
    6284             :  * The default format is StackFormat::SpiderMonkey.  Use StackFormat::V8
    6285             :  * in order to emulate V8's stack formatting.  StackFormat::Default can't be
    6286             :  * used here.
    6287             :  */
    6288             : extern JS_PUBLIC_API(void)
    6289             : SetStackFormat(JSContext* cx, StackFormat format);
    6290             : 
    6291             : extern JS_PUBLIC_API(StackFormat)
    6292             : GetStackFormat(JSContext* cx);
    6293             : 
    6294             : }
    6295             : 
    6296             : namespace JS {
    6297             : 
    6298             : /*
    6299             :  * This callback represents a request by the JS engine to open for reading the
    6300             :  * existing cache entry for the given global and char range that may contain a
    6301             :  * module. If a cache entry exists, the callback shall return 'true' and return
    6302             :  * the size, base address and an opaque file handle as outparams. If the
    6303             :  * callback returns 'true', the JS engine guarantees a call to
    6304             :  * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
    6305             :  * handle.
    6306             :  */
    6307             : typedef bool
    6308             : (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit,
    6309             :                                  size_t* size, const uint8_t** memory, intptr_t* handle);
    6310             : typedef void
    6311             : (* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle);
    6312             : 
    6313             : /** The list of reasons why an asm.js module may not be stored in the cache. */
    6314             : enum AsmJSCacheResult
    6315             : {
    6316             :     AsmJSCache_Success,
    6317             :     AsmJSCache_MIN = AsmJSCache_Success,
    6318             :     AsmJSCache_ModuleTooSmall,
    6319             :     AsmJSCache_SynchronousScript,
    6320             :     AsmJSCache_QuotaExceeded,
    6321             :     AsmJSCache_StorageInitFailure,
    6322             :     AsmJSCache_Disabled_Internal,
    6323             :     AsmJSCache_Disabled_ShellFlags,
    6324             :     AsmJSCache_Disabled_JitInspector,
    6325             :     AsmJSCache_InternalError,
    6326             :     AsmJSCache_Disabled_PrivateBrowsing,
    6327             :     AsmJSCache_LIMIT
    6328             : };
    6329             : 
    6330             : /*
    6331             :  * This callback represents a request by the JS engine to open for writing a
    6332             :  * cache entry of the given size for the given global and char range containing
    6333             :  * the just-compiled module. If cache entry space is available, the callback
    6334             :  * shall return 'true' and return the base address and an opaque file handle as
    6335             :  * outparams. If the callback returns 'true', the JS engine guarantees a call
    6336             :  * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
    6337             :  * handle.
    6338             :  */
    6339             : typedef AsmJSCacheResult
    6340             : (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, const char16_t* begin,
    6341             :                                   const char16_t* end, size_t size,
    6342             :                                   uint8_t** memory, intptr_t* handle);
    6343             : typedef void
    6344             : (* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle);
    6345             : 
    6346             : struct AsmJSCacheOps
    6347             : {
    6348             :     OpenAsmJSCacheEntryForReadOp openEntryForRead;
    6349             :     CloseAsmJSCacheEntryForReadOp closeEntryForRead;
    6350             :     OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
    6351             :     CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
    6352             : };
    6353             : 
    6354             : extern JS_PUBLIC_API(void)
    6355             : SetAsmJSCacheOps(JSContext* cx, const AsmJSCacheOps* callbacks);
    6356             : 
    6357             : /**
    6358             :  * Return the buildId (represented as a sequence of characters) associated with
    6359             :  * the currently-executing build. If the JS engine is embedded such that a
    6360             :  * single cache entry can be observed by different compiled versions of the JS
    6361             :  * engine, it is critical that the buildId shall change for each new build of
    6362             :  * the JS engine.
    6363             :  */
    6364             : typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
    6365             : 
    6366             : typedef bool
    6367             : (* BuildIdOp)(BuildIdCharVector* buildId);
    6368             : 
    6369             : extern JS_PUBLIC_API(void)
    6370             : SetBuildIdOp(JSContext* cx, BuildIdOp buildIdOp);
    6371             : 
    6372             : /**
    6373             :  * The WasmModule interface allows the embedding to hold a reference to the
    6374             :  * underying C++ implementation of a JS WebAssembly.Module object for purposes
    6375             :  * of (de)serialization off the object's JSRuntime's thread.
    6376             :  *
    6377             :  * - Serialization starts when WebAssembly.Module is passed to the
    6378             :  * structured-clone algorithm. JS::GetWasmModule is called on the JSRuntime
    6379             :  * thread that initiated the structured clone to get the JS::WasmModule.
    6380             :  * This interface is then taken to a background thread where serializedSize()
    6381             :  * and serialize() are called to write the object to two files: a bytecode file
    6382             :  * that always allows successful deserialization and a compiled-code file keyed
    6383             :  * on cpu- and build-id that may become invalid if either of these change between
    6384             :  * serialization and deserialization. After serialization, the reference is
    6385             :  * dropped from the background thread.
    6386             :  *
    6387             :  * - Deserialization starts when the structured clone algorithm encounters a
    6388             :  * serialized WebAssembly.Module. On a background thread, the compiled-code file
    6389             :  * is opened and CompiledWasmModuleAssumptionsMatch is called to see if it is
    6390             :  * still valid (as described above). DeserializeWasmModule is then called to
    6391             :  * construct a JS::WasmModule (also on the background thread), passing the
    6392             :  * bytecode file descriptor and, if valid, the compiled-code file descriptor.
    6393             :  * The JS::WasmObject is then transported to the JSRuntime thread (which
    6394             :  * originated the request) and the wrapping WebAssembly.Module object is created
    6395             :  * by calling createObject().
    6396             :  */
    6397             : 
    6398           0 : struct WasmModule : js::AtomicRefCounted<WasmModule>
    6399             : {
    6400           0 :     virtual ~WasmModule() {}
    6401             : 
    6402             :     virtual void serializedSize(size_t* maybeBytecodeSize, size_t* maybeCompiledSize) const = 0;
    6403             :     virtual void serialize(uint8_t* maybeBytecodeBegin, size_t maybeBytecodeSize,
    6404             :                            uint8_t* maybeCompiledBegin, size_t maybeCompiledSize) const = 0;
    6405             : 
    6406             :     virtual JSObject* createObject(JSContext* cx) = 0;
    6407             : };
    6408             : 
    6409             : extern JS_PUBLIC_API(bool)
    6410             : IsWasmModuleObject(HandleObject obj);
    6411             : 
    6412             : extern JS_PUBLIC_API(RefPtr<WasmModule>)
    6413             : GetWasmModule(HandleObject obj);
    6414             : 
    6415             : extern JS_PUBLIC_API(bool)
    6416             : CompiledWasmModuleAssumptionsMatch(PRFileDesc* compiled, BuildIdCharVector&& buildId);
    6417             : 
    6418             : extern JS_PUBLIC_API(RefPtr<WasmModule>)
    6419             : DeserializeWasmModule(PRFileDesc* bytecode, PRFileDesc* maybeCompiled, BuildIdCharVector&& buildId,
    6420             :                       JS::UniqueChars filename, unsigned line, unsigned column);
    6421             : 
    6422             : /**
    6423             :  * Convenience class for imitating a JS level for-of loop. Typical usage:
    6424             :  *
    6425             :  *     ForOfIterator it(cx);
    6426             :  *     if (!it.init(iterable))
    6427             :  *       return false;
    6428             :  *     RootedValue val(cx);
    6429             :  *     while (true) {
    6430             :  *       bool done;
    6431             :  *       if (!it.next(&val, &done))
    6432             :  *         return false;
    6433             :  *       if (done)
    6434             :  *         break;
    6435             :  *       if (!DoStuff(cx, val))
    6436             :  *         return false;
    6437             :  *     }
    6438             :  */
    6439           4 : class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
    6440             :   protected:
    6441             :     JSContext* cx_;
    6442             :     /*
    6443             :      * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
    6444             :      * to optimize iteration across arrays.
    6445             :      *
    6446             :      *  Case 1: Regular Iteration
    6447             :      *      iterator - pointer to the iterator object.
    6448             :      *      index - fixed to NOT_ARRAY (== UINT32_MAX)
    6449             :      *
    6450             :      *  Case 2: Optimized Array Iteration
    6451             :      *      iterator - pointer to the array object.
    6452             :      *      index - current position in array.
    6453             :      *
    6454             :      * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
    6455             :      */
    6456             :     JS::RootedObject iterator;
    6457             :     uint32_t index;
    6458             : 
    6459             :     static const uint32_t NOT_ARRAY = UINT32_MAX;
    6460             : 
    6461             :     ForOfIterator(const ForOfIterator&) = delete;
    6462             :     ForOfIterator& operator=(const ForOfIterator&) = delete;
    6463             : 
    6464             :   public:
    6465           4 :     explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
    6466             : 
    6467             :     enum NonIterableBehavior {
    6468             :         ThrowOnNonIterable,
    6469             :         AllowNonIterable
    6470             :     };
    6471             : 
    6472             :     /**
    6473             :      * Initialize the iterator.  If AllowNonIterable is passed then if getting
    6474             :      * the @@iterator property from iterable returns undefined init() will just
    6475             :      * return true instead of throwing.  Callers must then check
    6476             :      * valueIsIterable() before continuing with the iteration.
    6477             :      */
    6478             :     bool init(JS::HandleValue iterable,
    6479             :               NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
    6480             : 
    6481             :     /**
    6482             :      * Get the next value from the iterator.  If false *done is true
    6483             :      * after this call, do not examine val.
    6484             :      */
    6485             :     bool next(JS::MutableHandleValue val, bool* done);
    6486             : 
    6487             :     /**
    6488             :      * Close the iterator.
    6489             :      * For the case that completion type is throw.
    6490             :      */
    6491             :     void closeThrow();
    6492             : 
    6493             :     /**
    6494             :      * If initialized with throwOnNonCallable = false, check whether
    6495             :      * the value is iterable.
    6496             :      */
    6497           4 :     bool valueIsIterable() const {
    6498           4 :         return iterator;
    6499             :     }
    6500             : 
    6501             :   private:
    6502             :     inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done);
    6503             :     bool materializeArrayIterator();
    6504             : };
    6505             : 
    6506             : 
    6507             : /**
    6508             :  * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS
    6509             :  * engine may call the large-allocation-failure callback, if set, to allow the
    6510             :  * embedding to flush caches, possibly perform shrinking GCs, etc. to make some
    6511             :  * room. The allocation will then be retried (and may still fail.) This callback
    6512             :  * can be called on any thread and must be set at most once in a process.
    6513             :  */
    6514             : 
    6515             : typedef void
    6516             : (* LargeAllocationFailureCallback)();
    6517             : 
    6518             : extern JS_PUBLIC_API(void)
    6519             : SetProcessLargeAllocationFailureCallback(LargeAllocationFailureCallback afc);
    6520             : 
    6521             : /**
    6522             :  * Unlike the error reporter, which is only called if the exception for an OOM
    6523             :  * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
    6524             :  * at the OOM site to allow the embedding to capture the current state of heap
    6525             :  * allocation before anything is freed. If the large-allocation-failure callback
    6526             :  * is called at all (not all allocation sites call the large-allocation-failure
    6527             :  * callback on failure), it is called before the out-of-memory callback; the
    6528             :  * out-of-memory callback is only called if the allocation still fails after the
    6529             :  * large-allocation-failure callback has returned.
    6530             :  */
    6531             : 
    6532             : typedef void
    6533             : (* OutOfMemoryCallback)(JSContext* cx, void* data);
    6534             : 
    6535             : extern JS_PUBLIC_API(void)
    6536             : SetOutOfMemoryCallback(JSContext* cx, OutOfMemoryCallback cb, void* data);
    6537             : 
    6538             : /**
    6539             :  * Capture all frames.
    6540             :  */
    6541             : struct AllFrames { };
    6542             : 
    6543             : /**
    6544             :  * Capture at most this many frames.
    6545             :  */
    6546             : struct MaxFrames
    6547             : {
    6548             :     uint32_t maxFrames;
    6549             : 
    6550        2028 :     explicit MaxFrames(uint32_t max)
    6551        2028 :       : maxFrames(max)
    6552             :     {
    6553        2028 :         MOZ_ASSERT(max > 0);
    6554        2028 :     }
    6555             : };
    6556             : 
    6557             : /**
    6558             :  * Capture the first frame with the given principals. By default, do not
    6559             :  * consider self-hosted frames with the given principals as satisfying the stack
    6560             :  * capture.
    6561             :  */
    6562             : struct JS_PUBLIC_API(FirstSubsumedFrame)
    6563             : {
    6564             :     JSContext* cx;
    6565             :     JSPrincipals* principals;
    6566             :     bool ignoreSelfHosted;
    6567             : 
    6568             :     /**
    6569             :      * Use the cx's current compartment's principals.
    6570             :      */
    6571             :     explicit FirstSubsumedFrame(JSContext* cx, bool ignoreSelfHostedFrames = true);
    6572             : 
    6573           0 :     explicit FirstSubsumedFrame(JSContext* ctx, JSPrincipals* p, bool ignoreSelfHostedFrames = true)
    6574           0 :       : cx(ctx)
    6575             :       , principals(p)
    6576           0 :       , ignoreSelfHosted(ignoreSelfHostedFrames)
    6577             :     {
    6578           0 :         if (principals)
    6579           0 :             JS_HoldPrincipals(principals);
    6580           0 :     }
    6581             : 
    6582             :     // No copying because we want to avoid holding and dropping principals
    6583             :     // unnecessarily.
    6584             :     FirstSubsumedFrame(const FirstSubsumedFrame&) = delete;
    6585             :     FirstSubsumedFrame& operator=(const FirstSubsumedFrame&) = delete;
    6586             : 
    6587           0 :     FirstSubsumedFrame(FirstSubsumedFrame&& rhs)
    6588           0 :       : principals(rhs.principals)
    6589           0 :       , ignoreSelfHosted(rhs.ignoreSelfHosted)
    6590             :     {
    6591           0 :         MOZ_ASSERT(this != &rhs, "self move disallowed");
    6592           0 :         rhs.principals = nullptr;
    6593           0 :     }
    6594             : 
    6595             :     FirstSubsumedFrame& operator=(FirstSubsumedFrame&& rhs) {
    6596             :         new (this) FirstSubsumedFrame(mozilla::Move(rhs));
    6597             :         return *this;
    6598             :     }
    6599             : 
    6600           0 :     ~FirstSubsumedFrame() {
    6601           0 :         if (principals)
    6602           0 :             JS_DropPrincipals(cx, principals);
    6603           0 :     }
    6604             : };
    6605             : 
    6606             : using StackCapture = mozilla::Variant<AllFrames, MaxFrames, FirstSubsumedFrame>;
    6607             : 
    6608             : /**
    6609             :  * Capture the current call stack as a chain of SavedFrame JSObjects, and set
    6610             :  * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there
    6611             :  * are no JS frames on the stack.
    6612             :  *
    6613             :  * The |capture| parameter describes the portion of the JS stack to capture:
    6614             :  *
    6615             :  *   * |JS::AllFrames|: Capture all frames on the stack.
    6616             :  *
    6617             :  *   * |JS::MaxFrames|: Capture no more than |JS::MaxFrames::maxFrames| from the
    6618             :  *      stack.
    6619             :  *
    6620             :  *   * |JS::FirstSubsumedFrame|: Capture the first frame whose principals are
    6621             :  *     subsumed by |JS::FirstSubsumedFrame::principals|. By default, do not
    6622             :  *     consider self-hosted frames; this can be controlled via the
    6623             :  *     |JS::FirstSubsumedFrame::ignoreSelfHosted| flag. Do not capture any async
    6624             :  *     stack.
    6625             :  */
    6626             : extern JS_PUBLIC_API(bool)
    6627             : CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp,
    6628             :                     StackCapture&& capture = StackCapture(AllFrames()));
    6629             : 
    6630             : /*
    6631             :  * This is a utility function for preparing an async stack to be used
    6632             :  * by some other object.  This may be used when you need to treat a
    6633             :  * given stack trace as an async parent.  If you just need to capture
    6634             :  * the current stack, async parents and all, use CaptureCurrentStack
    6635             :  * instead.
    6636             :  *
    6637             :  * Here |asyncStack| is the async stack to prepare.  It is copied into
    6638             :  * |cx|'s current compartment, and the newest frame is given
    6639             :  * |asyncCause| as its asynchronous cause.  If |maxFrameCount| is
    6640             :  * non-zero, capture at most the youngest |maxFrameCount| frames.  The
    6641             :  * new stack object is written to |stackp|.  Returns true on success,
    6642             :  * or sets an exception and returns |false| on error.
    6643             :  */
    6644             : extern JS_PUBLIC_API(bool)
    6645             : CopyAsyncStack(JSContext* cx, HandleObject asyncStack,
    6646             :                HandleString asyncCause, MutableHandleObject stackp,
    6647             :                unsigned maxFrameCount);
    6648             : 
    6649             : /*
    6650             :  * Accessors for working with SavedFrame JSObjects
    6651             :  *
    6652             :  * Each of these functions assert that if their `HandleObject savedFrame`
    6653             :  * argument is non-null, its JSClass is the SavedFrame class (or it is a
    6654             :  * cross-compartment or Xray wrapper around an object with the SavedFrame class)
    6655             :  * and the object is not the SavedFrame.prototype object.
    6656             :  *
    6657             :  * Each of these functions will find the first SavedFrame object in the chain
    6658             :  * whose underlying stack frame principals are subsumed by the cx's current
    6659             :  * compartment's principals, and operate on that SavedFrame object. This
    6660             :  * prevents leaking information about privileged frames to un-privileged
    6661             :  * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the
    6662             :  * same compartment as the cx, and the various out parameters are _NOT_
    6663             :  * guaranteed to be in the same compartment as cx.
    6664             :  *
    6665             :  * You may consider or skip over self-hosted frames by passing
    6666             :  * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude`
    6667             :  * respectively.
    6668             :  *
    6669             :  * Additionally, it may be the case that there is no such SavedFrame object
    6670             :  * whose captured frame's principals are subsumed by the caller's compartment's
    6671             :  * principals! If the `HandleObject savedFrame` argument is null, or the
    6672             :  * caller's principals do not subsume any of the chained SavedFrame object's
    6673             :  * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully)
    6674             :  * sane default value is chosen for the out param.
    6675             :  *
    6676             :  * See also `js/src/doc/SavedFrame/SavedFrame.md`.
    6677             :  */
    6678             : 
    6679             : enum class SavedFrameResult {
    6680             :     Ok,
    6681             :     AccessDenied
    6682             : };
    6683             : 
    6684             : enum class SavedFrameSelfHosted {
    6685             :     Include,
    6686             :     Exclude
    6687             : };
    6688             : 
    6689             : /**
    6690             :  * Given a SavedFrame JSObject, get its source property. Defaults to the empty
    6691             :  * string.
    6692             :  */
    6693             : extern JS_PUBLIC_API(SavedFrameResult)
    6694             : GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep,
    6695             :                     SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6696             : 
    6697             : /**
    6698             :  * Given a SavedFrame JSObject, get its line property. Defaults to 0.
    6699             :  */
    6700             : extern JS_PUBLIC_API(SavedFrameResult)
    6701             : GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep,
    6702             :                   SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6703             : 
    6704             : /**
    6705             :  * Given a SavedFrame JSObject, get its column property. Defaults to 0.
    6706             :  */
    6707             : extern JS_PUBLIC_API(SavedFrameResult)
    6708             : GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp,
    6709             :                     SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6710             : 
    6711             : /**
    6712             :  * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr
    6713             :  * if SpiderMonkey was unable to infer a name for the captured frame's
    6714             :  * function. Defaults to nullptr.
    6715             :  */
    6716             : extern JS_PUBLIC_API(SavedFrameResult)
    6717             : GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep,
    6718             :                                  SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6719             : 
    6720             : /**
    6721             :  * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr.
    6722             :  */
    6723             : extern JS_PUBLIC_API(SavedFrameResult)
    6724             : GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep,
    6725             :                         SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6726             : 
    6727             : /**
    6728             :  * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr
    6729             :  * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_
    6730             :  * guaranteed to be in the cx's compartment. Defaults to nullptr.
    6731             :  */
    6732             : extern JS_PUBLIC_API(SavedFrameResult)
    6733             : GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp,
    6734             :                 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6735             : 
    6736             : /**
    6737             :  * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if
    6738             :  * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_
    6739             :  * guaranteed to be in the cx's compartment. Defaults to nullptr.
    6740             :  */
    6741             : extern JS_PUBLIC_API(SavedFrameResult)
    6742             : GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp,
    6743             :                     SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
    6744             : 
    6745             : /**
    6746             :  * Given a SavedFrame JSObject stack, stringify it in the same format as
    6747             :  * Error.prototype.stack. The stringified stack out parameter is placed in the
    6748             :  * cx's compartment. Defaults to the empty string.
    6749             :  *
    6750             :  * The same notes above about SavedFrame accessors applies here as well: cx
    6751             :  * doesn't need to be in stack's compartment, and stack can be null, a
    6752             :  * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object.
    6753             :  *
    6754             :  * Optional indent parameter specifies the number of white spaces to indent
    6755             :  * each line.
    6756             :  */
    6757             : extern JS_PUBLIC_API(bool)
    6758             : BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp,
    6759             :                  size_t indent = 0, js::StackFormat stackFormat = js::StackFormat::Default);
    6760             : 
    6761             : /**
    6762             :  * Return true iff the given object is either a SavedFrame object or wrapper
    6763             :  * around a SavedFrame object, and it is not the SavedFrame.prototype object.
    6764             :  */
    6765             : extern JS_PUBLIC_API(bool)
    6766             : IsSavedFrame(JSObject* obj);
    6767             : 
    6768             : } /* namespace JS */
    6769             : 
    6770             : 
    6771             : /* Stopwatch-based performance monitoring. */
    6772             : 
    6773             : namespace js {
    6774             : 
    6775             : class AutoStopwatch;
    6776             : 
    6777             : /**
    6778             :  * Abstract base class for a representation of the performance of a
    6779             :  * component. Embeddings interested in performance monitoring should
    6780             :  * provide a concrete implementation of this class, as well as the
    6781             :  * relevant callbacks (see below).
    6782             :  */
    6783             : struct JS_PUBLIC_API(PerformanceGroup) {
    6784             :     PerformanceGroup();
    6785             : 
    6786             :     // The current iteration of the event loop.
    6787             :     uint64_t iteration() const;
    6788             : 
    6789             :     // `true` if an instance of `AutoStopwatch` is already monitoring
    6790             :     // the performance of this performance group for this iteration
    6791             :     // of the event loop, `false` otherwise.
    6792             :     bool isAcquired(uint64_t it) const;
    6793             : 
    6794             :     // `true` if a specific instance of `AutoStopwatch` is already monitoring
    6795             :     // the performance of this performance group for this iteration
    6796             :     // of the event loop, `false` otherwise.
    6797             :     bool isAcquired(uint64_t it, const AutoStopwatch* owner) const;
    6798             : 
    6799             :     // Mark that an instance of `AutoStopwatch` is monitoring
    6800             :     // the performance of this group for a given iteration.
    6801             :     void acquire(uint64_t it, const AutoStopwatch* owner);
    6802             : 
    6803             :     // Mark that no `AutoStopwatch` is monitoring the
    6804             :     // performance of this group for the iteration.
    6805             :     void release(uint64_t it, const AutoStopwatch* owner);
    6806             : 
    6807             :     // The number of cycles spent in this group during this iteration
    6808             :     // of the event loop. Note that cycles are not a reliable measure,
    6809             :     // especially over short intervals. See Stopwatch.* for a more
    6810             :     // complete discussion on the imprecision of cycle measurement.
    6811             :     uint64_t recentCycles(uint64_t iteration) const;
    6812             :     void addRecentCycles(uint64_t iteration, uint64_t cycles);
    6813             : 
    6814             :     // The number of times this group has been activated during this
    6815             :     // iteration of the event loop.
    6816             :     uint64_t recentTicks(uint64_t iteration) const;
    6817             :     void addRecentTicks(uint64_t iteration, uint64_t ticks);
    6818             : 
    6819             :     // The number of microseconds spent doing CPOW during this
    6820             :     // iteration of the event loop.
    6821             :     uint64_t recentCPOW(uint64_t iteration) const;
    6822             :     void addRecentCPOW(uint64_t iteration, uint64_t CPOW);
    6823             : 
    6824             :     // Get rid of any data that pretends to be recent.
    6825             :     void resetRecentData();
    6826             : 
    6827             :     // `true` if new measures should be added to this group, `false`
    6828             :     // otherwise.
    6829             :     bool isActive() const;
    6830             :     void setIsActive(bool);
    6831             : 
    6832             :     // `true` if this group has been used in the current iteration,
    6833             :     // `false` otherwise.
    6834             :     bool isUsedInThisIteration() const;
    6835             :     void setIsUsedInThisIteration(bool);
    6836             :   protected:
    6837             :     // An implementation of `delete` for this object. Must be provided
    6838             :     // by the embedding.
    6839             :     virtual void Delete() = 0;
    6840             : 
    6841             :   private:
    6842             :     // The number of cycles spent in this group during this iteration
    6843             :     // of the event loop. Note that cycles are not a reliable measure,
    6844             :     // especially over short intervals. See Runtime.cpp for a more
    6845             :     // complete discussion on the imprecision of cycle measurement.
    6846             :     uint64_t recentCycles_;
    6847             : 
    6848             :     // The number of times this group has been activated during this
    6849             :     // iteration of the event loop.
    6850             :     uint64_t recentTicks_;
    6851             : 
    6852             :     // The number of microseconds spent doing CPOW during this
    6853             :     // iteration of the event loop.
    6854             :     uint64_t recentCPOW_;
    6855             : 
    6856             :     // The current iteration of the event loop. If necessary,
    6857             :     // may safely overflow.
    6858             :     uint64_t iteration_;
    6859             : 
    6860             :     // `true` if new measures should be added to this group, `false`
    6861             :     // otherwise.
    6862             :     bool isActive_;
    6863             : 
    6864             :     // `true` if this group has been used in the current iteration,
    6865             :     // `false` otherwise.
    6866             :     bool isUsedInThisIteration_;
    6867             : 
    6868             :     // The stopwatch currently monitoring the group,
    6869             :     // or `nullptr` if none. Used ony for comparison.
    6870             :     const AutoStopwatch* owner_;
    6871             : 
    6872             :   public:
    6873             :     // Compatibility with RefPtr<>
    6874             :     void AddRef();
    6875             :     void Release();
    6876             :     uint64_t refCount_;
    6877             : };
    6878             : 
    6879             : using PerformanceGroupVector = mozilla::Vector<RefPtr<js::PerformanceGroup>, 8, SystemAllocPolicy>;
    6880             : 
    6881             : /**
    6882             :  * Commit any Performance Monitoring data.
    6883             :  *
    6884             :  * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible
    6885             :  * to the outside world and can cancelled with a call to `ResetMonitoring`.
    6886             :  */
    6887             : extern JS_PUBLIC_API(bool)
    6888             : FlushPerformanceMonitoring(JSContext*);
    6889             : 
    6890             : /**
    6891             :  * Cancel any measurement that hasn't been committed.
    6892             :  */
    6893             : extern JS_PUBLIC_API(void)
    6894             : ResetPerformanceMonitoring(JSContext*);
    6895             : 
    6896             : /**
    6897             :  * Cleanup any memory used by performance monitoring.
    6898             :  */
    6899             : extern JS_PUBLIC_API(void)
    6900             : DisposePerformanceMonitoring(JSContext*);
    6901             : 
    6902             : /**
    6903             :  * Turn on/off stopwatch-based CPU monitoring.
    6904             :  *
    6905             :  * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank`
    6906             :  * may return `false` if monitoring could not be activated, which may
    6907             :  * happen if we are out of memory.
    6908             :  */
    6909             : extern JS_PUBLIC_API(bool)
    6910             : SetStopwatchIsMonitoringCPOW(JSContext*, bool);
    6911             : extern JS_PUBLIC_API(bool)
    6912             : GetStopwatchIsMonitoringCPOW(JSContext*);
    6913             : extern JS_PUBLIC_API(bool)
    6914             : SetStopwatchIsMonitoringJank(JSContext*, bool);
    6915             : extern JS_PUBLIC_API(bool)
    6916             : GetStopwatchIsMonitoringJank(JSContext*);
    6917             : 
    6918             : // Extract the CPU rescheduling data.
    6919             : extern JS_PUBLIC_API(void)
    6920             : GetPerfMonitoringTestCpuRescheduling(JSContext*, uint64_t* stayed, uint64_t* moved);
    6921             : 
    6922             : 
    6923             : /**
    6924             :  * Add a number of microseconds to the time spent waiting on CPOWs
    6925             :  * since process start.
    6926             :  */
    6927             : extern JS_PUBLIC_API(void)
    6928             : AddCPOWPerformanceDelta(JSContext*, uint64_t delta);
    6929             : 
    6930             : typedef bool
    6931             : (*StopwatchStartCallback)(uint64_t, void*);
    6932             : extern JS_PUBLIC_API(bool)
    6933             : SetStopwatchStartCallback(JSContext*, StopwatchStartCallback, void*);
    6934             : 
    6935             : typedef bool
    6936             : (*StopwatchCommitCallback)(uint64_t, PerformanceGroupVector&, void*);
    6937             : extern JS_PUBLIC_API(bool)
    6938             : SetStopwatchCommitCallback(JSContext*, StopwatchCommitCallback, void*);
    6939             : 
    6940             : typedef bool
    6941             : (*GetGroupsCallback)(JSContext*, PerformanceGroupVector&, void*);
    6942             : extern JS_PUBLIC_API(bool)
    6943             : SetGetPerformanceGroupsCallback(JSContext*, GetGroupsCallback, void*);
    6944             : 
    6945             : } /* namespace js */
    6946             : 
    6947             : namespace js {
    6948             : 
    6949             : enum class CompletionKind {
    6950             :     Normal,
    6951             :     Return,
    6952             :     Throw
    6953             : };
    6954             : 
    6955             : } /* namespace js */
    6956             : 
    6957             : #endif /* jsapi_h */

Generated by: LCOV version 1.13