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