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

Generated by: LCOV version 1.13-14-ga5dd952