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