60ce2b5a6e3b9dff3bba750a8358842bbe9a7545
[gecko.git] / jsapi.h
blob60ce2b5a6e3b9dff3bba750a8358842bbe9a7545
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* JavaScript API. */
9 #ifndef jsapi_h
10 #define jsapi_h
12 #include "mozilla/AlreadyAddRefed.h"
13 #include "mozilla/FloatingPoint.h"
14 #include "mozilla/MemoryReporting.h"
15 #include "mozilla/Range.h"
16 #include "mozilla/RangedPtr.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/Variant.h"
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <stdio.h>
25 #include "jsalloc.h"
26 #include "jspubtd.h"
28 #include "js/CallArgs.h"
29 #include "js/Class.h"
30 #include "js/GCVector.h"
31 #include "js/HashTable.h"
32 #include "js/Id.h"
33 #include "js/Principals.h"
34 #include "js/RootingAPI.h"
35 #include "js/TracingAPI.h"
36 #include "js/Utility.h"
37 #include "js/Value.h"
38 #include "js/Vector.h"
40 /************************************************************************/
42 namespace JS {
44 class TwoByteChars;
46 #ifdef JS_DEBUG
48 class JS_PUBLIC_API(AutoCheckRequestDepth)
50 JSContext* cx;
51 public:
52 explicit AutoCheckRequestDepth(JSContext* cx);
53 explicit AutoCheckRequestDepth(js::ContextFriendFields* cx);
54 ~AutoCheckRequestDepth();
57 # define CHECK_REQUEST(cx) \
58 JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
60 #else
62 # define CHECK_REQUEST(cx) \
63 ((void) 0)
65 #endif /* JS_DEBUG */
67 /** AutoValueArray roots an internal fixed-size array of Values. */
68 template <size_t N>
69 class MOZ_RAII AutoValueArray : public AutoGCRooter
71 const size_t length_;
72 Value elements_[N];
74 public:
75 explicit AutoValueArray(JSContext* cx
76 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
77 : AutoGCRooter(cx, VALARRAY), length_(N)
79 /* Always initialize in case we GC before assignment. */
80 mozilla::PodArrayZero(elements_);
81 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
84 unsigned length() const { return length_; }
85 const Value* begin() const { return elements_; }
86 Value* begin() { return elements_; }
88 HandleValue operator[](unsigned i) const {
89 MOZ_ASSERT(i < N);
90 return HandleValue::fromMarkedLocation(&elements_[i]);
92 MutableHandleValue operator[](unsigned i) {
93 MOZ_ASSERT(i < N);
94 return MutableHandleValue::fromMarkedLocation(&elements_[i]);
97 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
100 template<class T>
101 class MOZ_RAII AutoVectorRooterBase : protected AutoGCRooter
103 typedef js::Vector<T, 8> VectorImpl;
104 VectorImpl vector;
106 public:
107 explicit AutoVectorRooterBase(JSContext* cx, ptrdiff_t tag
108 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
109 : AutoGCRooter(cx, tag), vector(cx)
111 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
114 explicit AutoVectorRooterBase(js::ContextFriendFields* cx, ptrdiff_t tag
115 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
116 : AutoGCRooter(cx, tag), vector(cx)
118 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
121 typedef T ElementType;
122 typedef typename VectorImpl::Range Range;
124 size_t length() const { return vector.length(); }
125 bool empty() const { return vector.empty(); }
127 bool append(const T& v) { return vector.append(v); }
128 bool appendN(const T& v, size_t len) { return vector.appendN(v, len); }
129 bool append(const T* ptr, size_t len) { return vector.append(ptr, len); }
130 bool appendAll(const AutoVectorRooterBase<T>& other) {
131 return vector.appendAll(other.vector);
134 bool insert(T* p, const T& val) { return vector.insert(p, val); }
136 /* For use when space has already been reserved. */
137 void infallibleAppend(const T& v) { vector.infallibleAppend(v); }
139 void popBack() { vector.popBack(); }
140 T popCopy() { return vector.popCopy(); }
142 bool growBy(size_t inc) {
143 size_t oldLength = vector.length();
144 if (!vector.growByUninitialized(inc))
145 return false;
146 makeRangeGCSafe(oldLength);
147 return true;
150 bool resize(size_t newLength) {
151 size_t oldLength = vector.length();
152 if (newLength <= oldLength) {
153 vector.shrinkBy(oldLength - newLength);
154 return true;
156 if (!vector.growByUninitialized(newLength - oldLength))
157 return false;
158 makeRangeGCSafe(oldLength);
159 return true;
162 void clear() { vector.clear(); }
164 bool reserve(size_t newLength) {
165 return vector.reserve(newLength);
168 JS::MutableHandle<T> operator[](size_t i) {
169 return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
171 JS::Handle<T> operator[](size_t i) const {
172 return JS::Handle<T>::fromMarkedLocation(&vector[i]);
175 const T* begin() const { return vector.begin(); }
176 T* begin() { return vector.begin(); }
178 const T* end() const { return vector.end(); }
179 T* end() { return vector.end(); }
181 Range all() { return vector.all(); }
183 const T& back() const { return vector.back(); }
185 friend void AutoGCRooter::trace(JSTracer* trc);
187 private:
188 void makeRangeGCSafe(size_t oldLength) {
189 T* t = vector.begin() + oldLength;
190 for (size_t i = oldLength; i < vector.length(); ++i, ++t)
191 memset(t, 0, sizeof(T));
194 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
197 template <typename T>
198 class MOZ_RAII AutoVectorRooter : public AutoVectorRooterBase<T>
200 public:
201 explicit AutoVectorRooter(JSContext* cx
202 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
203 : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
205 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
208 explicit AutoVectorRooter(js::ContextFriendFields* cx
209 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
210 : AutoVectorRooterBase<T>(cx, this->GetTag(T()))
212 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
215 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
218 typedef AutoVectorRooter<Value> AutoValueVector;
219 typedef AutoVectorRooter<jsid> AutoIdVector;
220 typedef AutoVectorRooter<JSObject*> AutoObjectVector;
222 using ValueVector = JS::GCVector<JS::Value>;
223 using IdVector = JS::GCVector<jsid>;
224 using ScriptVector = JS::GCVector<JSScript*>;
226 template<class Key, class Value>
227 class MOZ_RAII AutoHashMapRooter : protected AutoGCRooter
229 private:
230 typedef js::HashMap<Key, Value> HashMapImpl;
232 public:
233 explicit AutoHashMapRooter(JSContext* cx, ptrdiff_t tag
234 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
235 : AutoGCRooter(cx, tag), map(cx)
237 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
240 typedef Key KeyType;
241 typedef Value ValueType;
242 typedef typename HashMapImpl::Entry Entry;
243 typedef typename HashMapImpl::Lookup Lookup;
244 typedef typename HashMapImpl::Ptr Ptr;
245 typedef typename HashMapImpl::AddPtr AddPtr;
247 bool init(uint32_t len = 16) {
248 return map.init(len);
250 bool initialized() const {
251 return map.initialized();
253 Ptr lookup(const Lookup& l) const {
254 return map.lookup(l);
256 void remove(Ptr p) {
257 map.remove(p);
259 AddPtr lookupForAdd(const Lookup& l) const {
260 return map.lookupForAdd(l);
263 template<typename KeyInput, typename ValueInput>
264 bool add(AddPtr& p, const KeyInput& k, const ValueInput& v) {
265 return map.add(p, k, v);
268 bool add(AddPtr& p, const Key& k) {
269 return map.add(p, k);
272 template<typename KeyInput, typename ValueInput>
273 bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
274 return map.relookupOrAdd(p, k, v);
277 typedef typename HashMapImpl::Range Range;
278 Range all() const {
279 return map.all();
282 typedef typename HashMapImpl::Enum Enum;
284 void clear() {
285 map.clear();
288 void finish() {
289 map.finish();
292 bool empty() const {
293 return map.empty();
296 uint32_t count() const {
297 return map.count();
300 size_t capacity() const {
301 return map.capacity();
304 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
305 return map.sizeOfExcludingThis(mallocSizeOf);
307 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
308 return map.sizeOfIncludingThis(mallocSizeOf);
311 /************************************************** Shorthand operations */
313 bool has(const Lookup& l) const {
314 return map.has(l);
317 template<typename KeyInput, typename ValueInput>
318 bool put(const KeyInput& k, const ValueInput& v) {
319 return map.put(k, v);
322 template<typename KeyInput, typename ValueInput>
323 bool putNew(const KeyInput& k, const ValueInput& v) {
324 return map.putNew(k, v);
327 Ptr lookupWithDefault(const Key& k, const Value& defaultValue) {
328 return map.lookupWithDefault(k, defaultValue);
331 void remove(const Lookup& l) {
332 map.remove(l);
335 friend void AutoGCRooter::trace(JSTracer* trc);
337 private:
338 AutoHashMapRooter(const AutoHashMapRooter& hmr) = delete;
339 AutoHashMapRooter& operator=(const AutoHashMapRooter& hmr) = delete;
341 HashMapImpl map;
343 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
346 template<class T>
347 class MOZ_RAII AutoHashSetRooter : protected AutoGCRooter
349 private:
350 typedef js::HashSet<T> HashSetImpl;
352 public:
353 explicit AutoHashSetRooter(JSContext* cx, ptrdiff_t tag
354 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
355 : AutoGCRooter(cx, tag), set(cx)
357 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
360 typedef typename HashSetImpl::Lookup Lookup;
361 typedef typename HashSetImpl::Ptr Ptr;
362 typedef typename HashSetImpl::AddPtr AddPtr;
364 bool init(uint32_t len = 16) {
365 return set.init(len);
367 bool initialized() const {
368 return set.initialized();
370 Ptr lookup(const Lookup& l) const {
371 return set.lookup(l);
373 void remove(Ptr p) {
374 set.remove(p);
376 AddPtr lookupForAdd(const Lookup& l) const {
377 return set.lookupForAdd(l);
380 bool add(AddPtr& p, const T& t) {
381 return set.add(p, t);
384 bool relookupOrAdd(AddPtr& p, const Lookup& l, const T& t) {
385 return set.relookupOrAdd(p, l, t);
388 typedef typename HashSetImpl::Range Range;
389 Range all() const {
390 return set.all();
393 typedef typename HashSetImpl::Enum Enum;
395 void clear() {
396 set.clear();
399 void finish() {
400 set.finish();
403 bool empty() const {
404 return set.empty();
407 uint32_t count() const {
408 return set.count();
411 size_t capacity() const {
412 return set.capacity();
415 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
416 return set.sizeOfExcludingThis(mallocSizeOf);
418 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
419 return set.sizeOfIncludingThis(mallocSizeOf);
422 /************************************************** Shorthand operations */
424 bool has(const Lookup& l) const {
425 return set.has(l);
428 bool put(const T& t) {
429 return set.put(t);
432 bool putNew(const T& t) {
433 return set.putNew(t);
436 void remove(const Lookup& l) {
437 set.remove(l);
440 friend void AutoGCRooter::trace(JSTracer* trc);
442 private:
443 AutoHashSetRooter(const AutoHashSetRooter& hmr) = delete;
444 AutoHashSetRooter& operator=(const AutoHashSetRooter& hmr) = delete;
446 HashSetImpl set;
448 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
452 * Custom rooting behavior for internal and external clients.
454 class MOZ_RAII JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
456 public:
457 template <typename CX>
458 explicit CustomAutoRooter(CX* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
459 : AutoGCRooter(cx, CUSTOM)
461 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
464 friend void AutoGCRooter::trace(JSTracer* trc);
466 protected:
467 /** Supplied by derived class to trace roots. */
468 virtual void trace(JSTracer* trc) = 0;
470 private:
471 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
474 /** A handle to an array of rooted values. */
475 class HandleValueArray
477 const size_t length_;
478 const Value * const elements_;
480 HandleValueArray(size_t len, const Value* elements) : length_(len), elements_(elements) {}
482 public:
483 explicit HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
485 MOZ_IMPLICIT HandleValueArray(const AutoValueVector& values)
486 : length_(values.length()), elements_(values.begin()) {}
488 template <size_t N>
489 MOZ_IMPLICIT HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
491 /** CallArgs must already be rooted somewhere up the stack. */
492 MOZ_IMPLICIT HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
494 /** Use with care! Only call this if the data is guaranteed to be marked. */
495 static HandleValueArray fromMarkedLocation(size_t len, const Value* elements) {
496 return HandleValueArray(len, elements);
499 static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
500 MOZ_ASSERT(startIndex + len <= values.length());
501 return HandleValueArray(len, values.begin() + startIndex);
504 static HandleValueArray empty() {
505 return HandleValueArray(0, nullptr);
508 size_t length() const { return length_; }
509 const Value* begin() const { return elements_; }
511 HandleValue operator[](size_t i) const {
512 MOZ_ASSERT(i < length_);
513 return HandleValue::fromMarkedLocation(&elements_[i]);
517 } /* namespace JS */
519 /************************************************************************/
521 struct JSFreeOp {
522 private:
523 JSRuntime* runtime_;
525 protected:
526 explicit JSFreeOp(JSRuntime* rt)
527 : runtime_(rt) { }
529 public:
530 JSRuntime* runtime() const {
531 return runtime_;
535 /* Callbacks and their arguments. */
537 /************************************************************************/
539 typedef enum JSContextOp {
540 JSCONTEXT_NEW,
541 JSCONTEXT_DESTROY
542 } JSContextOp;
545 * The possible values for contextOp when the runtime calls the callback are:
546 * JSCONTEXT_NEW JS_NewContext successfully created a new JSContext
547 * instance. The callback can initialize the instance as
548 * required. If the callback returns false, the instance
549 * will be destroyed and JS_NewContext returns null. In
550 * this case the callback is not called again.
551 * JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The
552 * callback may perform its own cleanup and must always
553 * return true.
554 * Any other value For future compatibility the callback must do nothing
555 * and return true in this case.
557 typedef bool
558 (* JSContextCallback)(JSContext* cx, unsigned contextOp, void* data);
560 typedef enum JSGCStatus {
561 JSGC_BEGIN,
562 JSGC_END
563 } JSGCStatus;
565 typedef void
566 (* JSGCCallback)(JSRuntime* rt, JSGCStatus status, void* data);
568 typedef void
569 (* JSObjectsTenuredCallback)(JSRuntime* rt, void* data);
571 typedef enum JSFinalizeStatus {
573 * Called when preparing to sweep a group of compartments, before anything
574 * has been swept. The collector will not yield to the mutator before
575 * calling the callback with JSFINALIZE_GROUP_END status.
577 JSFINALIZE_GROUP_START,
580 * Called when preparing to sweep a group of compartments. Weak references
581 * to unmarked things have been removed and things that are not swept
582 * incrementally have been finalized at this point. The collector may yield
583 * to the mutator after this point.
585 JSFINALIZE_GROUP_END,
588 * Called at the end of collection when everything has been swept.
590 JSFINALIZE_COLLECTION_END
591 } JSFinalizeStatus;
593 typedef void
594 (* JSFinalizeCallback)(JSFreeOp* fop, JSFinalizeStatus status, bool isCompartment, void* data);
596 typedef void
597 (* JSWeakPointerZoneGroupCallback)(JSRuntime* rt, void* data);
599 typedef void
600 (* JSWeakPointerCompartmentCallback)(JSRuntime* rt, JSCompartment* comp, void* data);
602 typedef bool
603 (* JSInterruptCallback)(JSContext* cx);
605 typedef bool
606 (* JSEnqueuePromiseJobCallback)(JSContext* cx, JS::HandleObject job, void* data);
608 typedef void
609 (* JSErrorReporter)(JSContext* cx, const char* message, JSErrorReport* report);
612 * Possible exception types. These types are part of a JSErrorFormatString
613 * structure. They define which error to throw in case of a runtime error.
614 * JSEXN_NONE marks an unthrowable error.
616 typedef enum JSExnType {
617 JSEXN_NONE = -1,
618 JSEXN_ERR,
619 JSEXN_INTERNALERR,
620 JSEXN_EVALERR,
621 JSEXN_RANGEERR,
622 JSEXN_REFERENCEERR,
623 JSEXN_SYNTAXERR,
624 JSEXN_TYPEERR,
625 JSEXN_URIERR,
626 JSEXN_DEBUGGEEWOULDRUN,
627 JSEXN_LIMIT
628 } JSExnType;
630 typedef struct JSErrorFormatString {
631 /** The error message name in ASCII. */
632 const char* name;
634 /** The error format string in ASCII. */
635 const char* format;
637 /** The number of arguments to expand in the formatted error message. */
638 uint16_t argCount;
640 /** One of the JSExnType constants above. */
641 int16_t exnType;
642 } JSErrorFormatString;
644 typedef const JSErrorFormatString*
645 (* JSErrorCallback)(void* userRef, const unsigned errorNumber);
647 typedef bool
648 (* JSLocaleToUpperCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
650 typedef bool
651 (* JSLocaleToLowerCase)(JSContext* cx, JS::HandleString src, JS::MutableHandleValue rval);
653 typedef bool
654 (* JSLocaleCompare)(JSContext* cx, JS::HandleString src1, JS::HandleString src2,
655 JS::MutableHandleValue rval);
657 typedef bool
658 (* JSLocaleToUnicode)(JSContext* cx, const char* src, JS::MutableHandleValue rval);
661 * Callback used to ask the embedding for the cross compartment wrapper handler
662 * that implements the desired prolicy for this kind of object in the
663 * destination compartment. |obj| is the object to be wrapped. If |existing| is
664 * non-nullptr, it will point to an existing wrapper object that should be
665 * re-used if possible. |existing| is guaranteed to be a cross-compartment
666 * wrapper with a lazily-defined prototype and the correct global. It is
667 * guaranteed not to wrap a function.
669 typedef JSObject*
670 (* JSWrapObjectCallback)(JSContext* cx, JS::HandleObject existing, JS::HandleObject obj);
673 * Callback used by the wrap hook to ask the embedding to prepare an object
674 * for wrapping in a context. This might include unwrapping other wrappers
675 * or even finding a more suitable object for the new compartment.
677 typedef JSObject*
678 (* JSPreWrapCallback)(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
679 JS::HandleObject objectPassedToWrap);
681 struct JSWrapObjectCallbacks
683 JSWrapObjectCallback wrap;
684 JSPreWrapCallback preWrap;
687 typedef void
688 (* JSDestroyCompartmentCallback)(JSFreeOp* fop, JSCompartment* compartment);
690 typedef size_t
691 (* JSSizeOfIncludingThisCompartmentCallback)(mozilla::MallocSizeOf mallocSizeOf,
692 JSCompartment* compartment);
694 typedef void
695 (* JSZoneCallback)(JS::Zone* zone);
697 typedef void
698 (* JSCompartmentNameCallback)(JSRuntime* rt, JSCompartment* compartment,
699 char* buf, size_t bufsize);
701 /************************************************************************/
703 static MOZ_ALWAYS_INLINE JS::Value
704 JS_NumberValue(double d)
706 int32_t i;
707 d = JS::CanonicalizeNaN(d);
708 if (mozilla::NumberIsInt32(d, &i))
709 return JS::Int32Value(i);
710 return JS::DoubleValue(d);
713 /************************************************************************/
715 JS_PUBLIC_API(bool)
716 JS_StringHasBeenPinned(JSContext* cx, JSString* str);
718 namespace JS {
721 * Container class for passing in script source buffers to the JS engine. This
722 * not only groups the buffer and length values, it also provides a way to
723 * optionally pass ownership of the buffer to the JS engine without copying.
724 * Rules for use:
726 * 1) The data array must be allocated with js_malloc() or js_realloc() if
727 * ownership is being granted to the SourceBufferHolder.
728 * 2) If ownership is not given to the SourceBufferHolder, then the memory
729 * must be kept alive until the JS compilation is complete.
730 * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
731 * memory alive until JS compilation completes. Normally only the JS
732 * engine should be calling take().
734 * Example use:
736 * size_t length = 512;
737 * char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
738 * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
739 * JS::Compile(cx, options, srcBuf);
741 class MOZ_STACK_CLASS SourceBufferHolder final
743 public:
744 enum Ownership {
745 NoOwnership,
746 GiveOwnership
749 SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership)
750 : data_(data),
751 length_(dataLength),
752 ownsChars_(ownership == GiveOwnership)
754 // Ensure that null buffers properly return an unowned, empty,
755 // null-terminated string.
756 static const char16_t NullChar_ = 0;
757 if (!get()) {
758 data_ = &NullChar_;
759 length_ = 0;
760 ownsChars_ = false;
764 SourceBufferHolder(SourceBufferHolder&& other)
765 : data_(other.data_),
766 length_(other.length_),
767 ownsChars_(other.ownsChars_)
769 other.data_ = nullptr;
770 other.length_ = 0;
771 other.ownsChars_ = false;
774 ~SourceBufferHolder() {
775 if (ownsChars_)
776 js_free(const_cast<char16_t*>(data_));
779 // Access the underlying source buffer without affecting ownership.
780 const char16_t* get() const { return data_; }
782 // Length of the source buffer in char16_t code units (not bytes)
783 size_t length() const { return length_; }
785 // Returns true if the SourceBufferHolder owns the buffer and will free
786 // it upon destruction. If true, it is legal to call take().
787 bool ownsChars() const { return ownsChars_; }
789 // Retrieve and take ownership of the underlying data buffer. The caller
790 // is now responsible for calling js_free() on the returned value, *but only
791 // after JS script compilation has completed*.
793 // After the buffer has been taken the SourceBufferHolder functions as if
794 // it had been constructed on an unowned buffer; get() and length() still
795 // work. In order for this to be safe the taken buffer must be kept alive
796 // until after JS script compilation completes as noted above.
798 // Note, it's the caller's responsibility to check ownsChars() before taking
799 // the buffer. Taking and then free'ing an unowned buffer will have dire
800 // consequences.
801 char16_t* take() {
802 MOZ_ASSERT(ownsChars_);
803 ownsChars_ = false;
804 return const_cast<char16_t*>(data_);
807 private:
808 SourceBufferHolder(SourceBufferHolder&) = delete;
809 SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
811 const char16_t* data_;
812 size_t length_;
813 bool ownsChars_;
816 } /* namespace JS */
818 /************************************************************************/
820 /* Property attributes, set in JSPropertySpec and passed to API functions.
822 * NB: The data structure in which some of these values are stored only uses
823 * a uint8_t to store the relevant information. Proceed with caution if
824 * trying to reorder or change the the first byte worth of flags.
826 #define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
827 #define JSPROP_READONLY 0x02 /* not settable: assignment is no-op.
828 This flag is only valid when neither
829 JSPROP_GETTER nor JSPROP_SETTER is
830 set. */
831 #define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
832 #define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and
833 JS_DefineElement if getters/setters
834 are JSGetterOp/JSSetterOp */
835 #define JSPROP_GETTER 0x10 /* property holds getter function */
836 #define JSPROP_SETTER 0x20 /* property holds setter function */
837 #define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
838 property; don't copy the property on
839 set of the same-named property in an
840 object that delegates to a prototype
841 containing this property */
842 #define JSPROP_INTERNAL_USE_BIT 0x80 /* internal JS engine use only */
843 // 0x100 /* Unused */
844 #define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
845 instead of defaulting to class gsops
846 for property holding function */
848 #define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
850 // 0x800 /* Unused */
852 #define JSFUN_HAS_REST 0x1000 /* function has ...rest parameter. */
854 #define JSFUN_FLAGS_MASK 0x1e00 /* | of all the JSFUN_* flags */
857 * If set, will allow redefining a non-configurable property, but only on a
858 * non-DOM global. This is a temporary hack that will need to go away in bug
859 * 1105518.
861 #define JSPROP_REDEFINE_NONCONFIGURABLE 0x1000
864 * Resolve hooks and enumerate hooks must pass this flag when calling
865 * JS_Define* APIs to reify lazily-defined properties.
867 * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
868 * engine to skip the resolve hook when performing the lookup at the beginning
869 * of property definition. This keeps the resolve hook from accidentally
870 * triggering itself: unchecked recursion.
872 * For enumerate hooks, triggering the resolve hook would be merely silly, not
873 * fatal, except in some cases involving non-configurable properties.
875 #define JSPROP_RESOLVING 0x2000
877 #define JSPROP_IGNORE_ENUMERATE 0x4000 /* ignore the value in JSPROP_ENUMERATE.
878 This flag only valid when defining over
879 an existing property. */
880 #define JSPROP_IGNORE_READONLY 0x8000 /* ignore the value in JSPROP_READONLY.
881 This flag only valid when defining over
882 an existing property. */
883 #define JSPROP_IGNORE_PERMANENT 0x10000 /* ignore the value in JSPROP_PERMANENT.
884 This flag only valid when defining over
885 an existing property. */
886 #define JSPROP_IGNORE_VALUE 0x20000 /* ignore the Value in the descriptor. Nothing was
887 specified when passed to Object.defineProperty
888 from script. */
891 * The first call to JS_CallOnce by any thread in a process will call 'func'.
892 * Later calls to JS_CallOnce with the same JSCallOnceType object will be
893 * suppressed.
895 * Equivalently: each distinct JSCallOnceType object will allow one JS_CallOnce
896 * to invoke its JSInitCallback.
898 extern JS_PUBLIC_API(bool)
899 JS_CallOnce(JSCallOnceType* once, JSInitCallback func);
901 /** Microseconds since the epoch, midnight, January 1, 1970 UTC. */
902 extern JS_PUBLIC_API(int64_t)
903 JS_Now(void);
905 /** Don't want to export data, so provide accessors for non-inline Values. */
906 extern JS_PUBLIC_API(JS::Value)
907 JS_GetNaNValue(JSContext* cx);
909 extern JS_PUBLIC_API(JS::Value)
910 JS_GetNegativeInfinityValue(JSContext* cx);
912 extern JS_PUBLIC_API(JS::Value)
913 JS_GetPositiveInfinityValue(JSContext* cx);
915 extern JS_PUBLIC_API(JS::Value)
916 JS_GetEmptyStringValue(JSContext* cx);
918 extern JS_PUBLIC_API(JSString*)
919 JS_GetEmptyString(JSRuntime* rt);
921 extern JS_PUBLIC_API(bool)
922 JS_ValueToObject(JSContext* cx, JS::HandleValue v, JS::MutableHandleObject objp);
924 extern JS_PUBLIC_API(JSFunction*)
925 JS_ValueToFunction(JSContext* cx, JS::HandleValue v);
927 extern JS_PUBLIC_API(JSFunction*)
928 JS_ValueToConstructor(JSContext* cx, JS::HandleValue v);
930 extern JS_PUBLIC_API(JSString*)
931 JS_ValueToSource(JSContext* cx, JS::Handle<JS::Value> v);
933 extern JS_PUBLIC_API(bool)
934 JS_DoubleIsInt32(double d, int32_t* ip);
936 extern JS_PUBLIC_API(JSType)
937 JS_TypeOfValue(JSContext* cx, JS::Handle<JS::Value> v);
939 extern JS_PUBLIC_API(bool)
940 JS_StrictlyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
942 extern JS_PUBLIC_API(bool)
943 JS_LooselyEqual(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* equal);
945 extern JS_PUBLIC_API(bool)
946 JS_SameValue(JSContext* cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool* same);
948 /** True iff fun is the global eval function. */
949 extern JS_PUBLIC_API(bool)
950 JS_IsBuiltinEvalFunction(JSFunction* fun);
952 /** True iff fun is the Function constructor. */
953 extern JS_PUBLIC_API(bool)
954 JS_IsBuiltinFunctionConstructor(JSFunction* fun);
956 /************************************************************************/
959 * Locking, contexts, and memory allocation.
961 * It is important that SpiderMonkey be initialized, and the first runtime and
962 * first context be created, in a single-threaded fashion. Otherwise the
963 * behavior of the library is undefined.
964 * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
967 extern JS_PUBLIC_API(JSRuntime*)
968 JS_NewRuntime(uint32_t maxbytes,
969 uint32_t maxNurseryBytes = JS::DefaultNurseryBytes,
970 JSRuntime* parentRuntime = nullptr);
972 extern JS_PUBLIC_API(void)
973 JS_DestroyRuntime(JSRuntime* rt);
975 typedef double (*JS_CurrentEmbedderTimeFunction)();
978 * The embedding can specify a time function that will be used in some
979 * situations. The function can return the time however it likes; but
980 * the norm is to return times in units of milliseconds since an
981 * arbitrary, but consistent, epoch. If the time function is not set,
982 * a built-in default will be used.
984 JS_PUBLIC_API(void)
985 JS_SetCurrentEmbedderTimeFunction(JS_CurrentEmbedderTimeFunction timeFn);
988 * Return the time as computed using the current time function, or a
989 * suitable default if one has not been set.
991 JS_PUBLIC_API(double)
992 JS_GetCurrentEmbedderTime();
994 JS_PUBLIC_API(void*)
995 JS_GetRuntimePrivate(JSRuntime* rt);
997 extern JS_PUBLIC_API(JSRuntime*)
998 JS_GetRuntime(JSContext* cx);
1000 extern JS_PUBLIC_API(JSRuntime*)
1001 JS_GetParentRuntime(JSRuntime* rt);
1003 JS_PUBLIC_API(void)
1004 JS_SetRuntimePrivate(JSRuntime* rt, void* data);
1006 extern JS_PUBLIC_API(void)
1007 JS_BeginRequest(JSContext* cx);
1009 extern JS_PUBLIC_API(void)
1010 JS_EndRequest(JSContext* cx);
1012 extern JS_PUBLIC_API(void)
1013 JS_SetFutexCanWait(JSRuntime* rt);
1015 namespace js {
1017 void
1018 AssertHeapIsIdle(JSRuntime* rt);
1020 void
1021 AssertHeapIsIdle(JSContext* cx);
1023 } /* namespace js */
1025 class MOZ_RAII JSAutoRequest
1027 public:
1028 explicit JSAutoRequest(JSContext* cx
1029 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
1030 : mContext(cx)
1032 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
1033 JS_BeginRequest(mContext);
1035 ~JSAutoRequest() {
1036 JS_EndRequest(mContext);
1039 protected:
1040 JSContext* mContext;
1041 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1043 #if 0
1044 private:
1045 static void* operator new(size_t) CPP_THROW_NEW { return 0; }
1046 static void operator delete(void*, size_t) { }
1047 #endif
1050 extern JS_PUBLIC_API(void)
1051 JS_SetContextCallback(JSRuntime* rt, JSContextCallback cxCallback, void* data);
1053 extern JS_PUBLIC_API(JSContext*)
1054 JS_NewContext(JSRuntime* rt, size_t stackChunkSize);
1056 extern JS_PUBLIC_API(void)
1057 JS_DestroyContext(JSContext* cx);
1059 extern JS_PUBLIC_API(void)
1060 JS_DestroyContextNoGC(JSContext* cx);
1062 extern JS_PUBLIC_API(void*)
1063 JS_GetContextPrivate(JSContext* cx);
1065 extern JS_PUBLIC_API(void)
1066 JS_SetContextPrivate(JSContext* cx, void* data);
1068 extern JS_PUBLIC_API(void*)
1069 JS_GetSecondContextPrivate(JSContext* cx);
1071 extern JS_PUBLIC_API(void)
1072 JS_SetSecondContextPrivate(JSContext* cx, void* data);
1074 extern JS_PUBLIC_API(JSRuntime*)
1075 JS_GetRuntime(JSContext* cx);
1077 extern JS_PUBLIC_API(JSContext*)
1078 JS_ContextIterator(JSRuntime* rt, JSContext** iterp);
1080 extern JS_PUBLIC_API(JSVersion)
1081 JS_GetVersion(JSContext* cx);
1084 * Mutate the version on the compartment. This is generally discouraged, but
1085 * necessary to support the version mutation in the js and xpc shell command
1086 * set.
1088 * It would be nice to put this in jsfriendapi, but the linkage requirements
1089 * of the shells make that impossible.
1091 JS_PUBLIC_API(void)
1092 JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version);
1094 extern JS_PUBLIC_API(const char*)
1095 JS_VersionToString(JSVersion version);
1097 extern JS_PUBLIC_API(JSVersion)
1098 JS_StringToVersion(const char* string);
1100 namespace JS {
1102 class JS_PUBLIC_API(RuntimeOptions) {
1103 public:
1104 RuntimeOptions()
1105 : baseline_(true),
1106 ion_(true),
1107 asmJS_(true),
1108 wasm_(false),
1109 throwOnAsmJSValidationFailure_(false),
1110 nativeRegExp_(true),
1111 unboxedArrays_(false),
1112 asyncStack_(true),
1113 throwOnDebuggeeWouldRun_(true),
1114 dumpStackOnDebuggeeWouldRun_(false),
1115 werror_(false),
1116 strictMode_(false),
1117 extraWarnings_(false)
1121 bool baseline() const { return baseline_; }
1122 RuntimeOptions& setBaseline(bool flag) {
1123 baseline_ = flag;
1124 return *this;
1126 RuntimeOptions& toggleBaseline() {
1127 baseline_ = !baseline_;
1128 return *this;
1131 bool ion() const { return ion_; }
1132 RuntimeOptions& setIon(bool flag) {
1133 ion_ = flag;
1134 return *this;
1136 RuntimeOptions& toggleIon() {
1137 ion_ = !ion_;
1138 return *this;
1141 bool asmJS() const { return asmJS_; }
1142 RuntimeOptions& setAsmJS(bool flag) {
1143 asmJS_ = flag;
1144 return *this;
1146 RuntimeOptions& toggleAsmJS() {
1147 asmJS_ = !asmJS_;
1148 return *this;
1151 bool wasm() const { return wasm_; }
1152 RuntimeOptions& setWasm(bool flag) {
1153 wasm_ = flag;
1154 return *this;
1156 RuntimeOptions& toggleWasm() {
1157 wasm_ = !wasm_;
1158 return *this;
1161 bool throwOnAsmJSValidationFailure() const { return throwOnAsmJSValidationFailure_; }
1162 RuntimeOptions& setThrowOnAsmJSValidationFailure(bool flag) {
1163 throwOnAsmJSValidationFailure_ = flag;
1164 return *this;
1166 RuntimeOptions& toggleThrowOnAsmJSValidationFailure() {
1167 throwOnAsmJSValidationFailure_ = !throwOnAsmJSValidationFailure_;
1168 return *this;
1171 bool nativeRegExp() const { return nativeRegExp_; }
1172 RuntimeOptions& setNativeRegExp(bool flag) {
1173 nativeRegExp_ = flag;
1174 return *this;
1177 bool unboxedArrays() const { return unboxedArrays_; }
1178 RuntimeOptions& setUnboxedArrays(bool flag) {
1179 unboxedArrays_ = flag;
1180 return *this;
1183 bool asyncStack() const { return asyncStack_; }
1184 RuntimeOptions& setAsyncStack(bool flag) {
1185 asyncStack_ = flag;
1186 return *this;
1189 bool throwOnDebuggeeWouldRun() const { return throwOnDebuggeeWouldRun_; }
1190 RuntimeOptions& setThrowOnDebuggeeWouldRun(bool flag) {
1191 throwOnDebuggeeWouldRun_ = flag;
1192 return *this;
1195 bool dumpStackOnDebuggeeWouldRun() const { return dumpStackOnDebuggeeWouldRun_; }
1196 RuntimeOptions& setDumpStackOnDebuggeeWouldRun(bool flag) {
1197 dumpStackOnDebuggeeWouldRun_ = flag;
1198 return *this;
1201 bool werror() const { return werror_; }
1202 RuntimeOptions& setWerror(bool flag) {
1203 werror_ = flag;
1204 return *this;
1206 RuntimeOptions& toggleWerror() {
1207 werror_ = !werror_;
1208 return *this;
1211 bool strictMode() const { return strictMode_; }
1212 RuntimeOptions& setStrictMode(bool flag) {
1213 strictMode_ = flag;
1214 return *this;
1216 RuntimeOptions& toggleStrictMode() {
1217 strictMode_ = !strictMode_;
1218 return *this;
1221 bool extraWarnings() const { return extraWarnings_; }
1222 RuntimeOptions& setExtraWarnings(bool flag) {
1223 extraWarnings_ = flag;
1224 return *this;
1226 RuntimeOptions& toggleExtraWarnings() {
1227 extraWarnings_ = !extraWarnings_;
1228 return *this;
1231 private:
1232 bool baseline_ : 1;
1233 bool ion_ : 1;
1234 bool asmJS_ : 1;
1235 bool wasm_ : 1;
1236 bool throwOnAsmJSValidationFailure_ : 1;
1237 bool nativeRegExp_ : 1;
1238 bool unboxedArrays_ : 1;
1239 bool asyncStack_ : 1;
1240 bool throwOnDebuggeeWouldRun_ : 1;
1241 bool dumpStackOnDebuggeeWouldRun_ : 1;
1242 bool werror_ : 1;
1243 bool strictMode_ : 1;
1244 bool extraWarnings_ : 1;
1247 JS_PUBLIC_API(RuntimeOptions&)
1248 RuntimeOptionsRef(JSRuntime* rt);
1250 JS_PUBLIC_API(RuntimeOptions&)
1251 RuntimeOptionsRef(JSContext* cx);
1253 class JS_PUBLIC_API(ContextOptions) {
1254 public:
1255 ContextOptions()
1256 : privateIsNSISupports_(false),
1257 dontReportUncaught_(false),
1258 autoJSAPIOwnsErrorReporting_(false)
1262 bool privateIsNSISupports() const { return privateIsNSISupports_; }
1263 ContextOptions& setPrivateIsNSISupports(bool flag) {
1264 privateIsNSISupports_ = flag;
1265 return *this;
1267 ContextOptions& togglePrivateIsNSISupports() {
1268 privateIsNSISupports_ = !privateIsNSISupports_;
1269 return *this;
1272 bool dontReportUncaught() const { return dontReportUncaught_; }
1273 ContextOptions& setDontReportUncaught(bool flag) {
1274 dontReportUncaught_ = flag;
1275 return *this;
1277 ContextOptions& toggleDontReportUncaught() {
1278 dontReportUncaught_ = !dontReportUncaught_;
1279 return *this;
1282 bool autoJSAPIOwnsErrorReporting() const { return autoJSAPIOwnsErrorReporting_; }
1283 ContextOptions& setAutoJSAPIOwnsErrorReporting(bool flag) {
1284 autoJSAPIOwnsErrorReporting_ = flag;
1285 return *this;
1287 ContextOptions& toggleAutoJSAPIOwnsErrorReporting() {
1288 autoJSAPIOwnsErrorReporting_ = !autoJSAPIOwnsErrorReporting_;
1289 return *this;
1293 private:
1294 bool privateIsNSISupports_ : 1;
1295 bool dontReportUncaught_ : 1;
1296 // dontReportUncaught isn't respected by all JSAPI codepaths, particularly the
1297 // JS_ReportError* functions that eventually report the error even when dontReportUncaught is
1298 // set, if script is not running. We want a way to indicate that the embedder will always
1299 // handle any exceptions, and that SpiderMonkey should just leave them on the context. This is
1300 // the way we want to do all future error handling in Gecko - stealing the exception explicitly
1301 // from the context and handling it as per the situation. This will eventually become the
1302 // default and these 2 flags should go away.
1303 bool autoJSAPIOwnsErrorReporting_ : 1;
1306 JS_PUBLIC_API(ContextOptions&)
1307 ContextOptionsRef(JSContext* cx);
1309 class JS_PUBLIC_API(AutoSaveContextOptions) {
1310 public:
1311 explicit AutoSaveContextOptions(JSContext* cx)
1312 : cx_(cx),
1313 oldOptions_(ContextOptionsRef(cx_))
1317 ~AutoSaveContextOptions()
1319 ContextOptionsRef(cx_) = oldOptions_;
1322 private:
1323 JSContext* cx_;
1324 JS::ContextOptions oldOptions_;
1327 } /* namespace JS */
1329 extern JS_PUBLIC_API(const char*)
1330 JS_GetImplementationVersion(void);
1332 extern JS_PUBLIC_API(void)
1333 JS_SetDestroyCompartmentCallback(JSRuntime* rt, JSDestroyCompartmentCallback callback);
1335 extern JS_PUBLIC_API(void)
1336 JS_SetSizeOfIncludingThisCompartmentCallback(JSRuntime* rt,
1337 JSSizeOfIncludingThisCompartmentCallback callback);
1339 extern JS_PUBLIC_API(void)
1340 JS_SetDestroyZoneCallback(JSRuntime* rt, JSZoneCallback callback);
1342 extern JS_PUBLIC_API(void)
1343 JS_SetSweepZoneCallback(JSRuntime* rt, JSZoneCallback callback);
1345 extern JS_PUBLIC_API(void)
1346 JS_SetCompartmentNameCallback(JSRuntime* rt, JSCompartmentNameCallback callback);
1348 extern JS_PUBLIC_API(void)
1349 JS_SetWrapObjectCallbacks(JSRuntime* rt, const JSWrapObjectCallbacks* callbacks);
1351 extern JS_PUBLIC_API(void)
1352 JS_SetCompartmentPrivate(JSCompartment* compartment, void* data);
1354 extern JS_PUBLIC_API(void*)
1355 JS_GetCompartmentPrivate(JSCompartment* compartment);
1357 extern JS_PUBLIC_API(void)
1358 JS_SetZoneUserData(JS::Zone* zone, void* data);
1360 extern JS_PUBLIC_API(void*)
1361 JS_GetZoneUserData(JS::Zone* zone);
1363 extern JS_PUBLIC_API(bool)
1364 JS_WrapObject(JSContext* cx, JS::MutableHandleObject objp);
1366 extern JS_PUBLIC_API(bool)
1367 JS_WrapValue(JSContext* cx, JS::MutableHandleValue vp);
1369 extern JS_PUBLIC_API(JSObject*)
1370 JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
1372 extern JS_PUBLIC_API(bool)
1373 JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
1376 * At any time, a JSContext has a current (possibly-nullptr) compartment.
1377 * Compartments are described in:
1379 * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
1381 * The current compartment of a context may be changed. The preferred way to do
1382 * this is with JSAutoCompartment:
1384 * void foo(JSContext* cx, JSObject* obj) {
1385 * // in some compartment 'c'
1387 * JSAutoCompartment ac(cx, obj); // constructor enters
1388 * // in the compartment of 'obj'
1389 * } // destructor leaves
1390 * // back in compartment 'c'
1393 * For more complicated uses that don't neatly fit in a C++ stack frame, the
1394 * compartment can entered and left using separate function calls:
1396 * void foo(JSContext* cx, JSObject* obj) {
1397 * // in 'oldCompartment'
1398 * JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj);
1399 * // in the compartment of 'obj'
1400 * JS_LeaveCompartment(cx, oldCompartment);
1401 * // back in 'oldCompartment'
1404 * Note: these calls must still execute in a LIFO manner w.r.t all other
1405 * enter/leave calls on the context. Furthermore, only the return value of a
1406 * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
1407 * the corresponding JS_LeaveCompartment call.
1410 class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment)
1412 JSContext* cx_;
1413 JSCompartment* oldCompartment_;
1414 public:
1415 JSAutoCompartment(JSContext* cx, JSObject* target
1416 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
1417 JSAutoCompartment(JSContext* cx, JSScript* target
1418 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
1419 ~JSAutoCompartment();
1421 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1424 class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment)
1426 JSContext* cx_;
1427 JSCompartment* oldCompartment_;
1428 public:
1429 explicit JSAutoNullableCompartment(JSContext* cx, JSObject* targetOrNull
1430 MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
1431 ~JSAutoNullableCompartment();
1433 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1436 /** NB: This API is infallible; a nullptr return value does not indicate error. */
1437 extern JS_PUBLIC_API(JSCompartment*)
1438 JS_EnterCompartment(JSContext* cx, JSObject* target);
1440 extern JS_PUBLIC_API(void)
1441 JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment);
1443 typedef void (*JSIterateCompartmentCallback)(JSRuntime* rt, void* data, JSCompartment* compartment);
1446 * This function calls |compartmentCallback| on every compartment. Beware that
1447 * there is no guarantee that the compartment will survive after the callback
1448 * returns. Also, barriers are disabled via the TraceSession.
1450 extern JS_PUBLIC_API(void)
1451 JS_IterateCompartments(JSRuntime* rt, void* data,
1452 JSIterateCompartmentCallback compartmentCallback);
1455 * Initialize standard JS class constructors, prototypes, and any top-level
1456 * functions and constants associated with the standard classes (e.g. isNaN
1457 * for Number).
1459 * NB: This sets cx's global object to obj if it was null.
1461 extern JS_PUBLIC_API(bool)
1462 JS_InitStandardClasses(JSContext* cx, JS::Handle<JSObject*> obj);
1465 * Resolve id, which must contain either a string or an int, to a standard
1466 * class name in obj if possible, defining the class's constructor and/or
1467 * prototype and storing true in *resolved. If id does not name a standard
1468 * class or a top-level property induced by initializing a standard class,
1469 * store false in *resolved and just return true. Return false on error,
1470 * as usual for bool result-typed API entry points.
1472 * This API can be called directly from a global object class's resolve op,
1473 * to define standard classes lazily. The class's enumerate op should call
1474 * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
1475 * loops any classes not yet resolved lazily.
1477 extern JS_PUBLIC_API(bool)
1478 JS_ResolveStandardClass(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* resolved);
1480 extern JS_PUBLIC_API(bool)
1481 JS_MayResolveStandardClass(const JSAtomState& names, jsid id, JSObject* maybeObj);
1483 extern JS_PUBLIC_API(bool)
1484 JS_EnumerateStandardClasses(JSContext* cx, JS::HandleObject obj);
1486 extern JS_PUBLIC_API(bool)
1487 JS_GetClassObject(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1489 extern JS_PUBLIC_API(bool)
1490 JS_GetClassPrototype(JSContext* cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1492 namespace JS {
1495 * Determine if the given object is an instance/prototype/constructor for a standard
1496 * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
1499 extern JS_PUBLIC_API(JSProtoKey)
1500 IdentifyStandardInstance(JSObject* obj);
1502 extern JS_PUBLIC_API(JSProtoKey)
1503 IdentifyStandardPrototype(JSObject* obj);
1505 extern JS_PUBLIC_API(JSProtoKey)
1506 IdentifyStandardInstanceOrPrototype(JSObject* obj);
1508 extern JS_PUBLIC_API(JSProtoKey)
1509 IdentifyStandardConstructor(JSObject* obj);
1511 extern JS_PUBLIC_API(void)
1512 ProtoKeyToId(JSContext* cx, JSProtoKey key, JS::MutableHandleId idp);
1514 } /* namespace JS */
1516 extern JS_PUBLIC_API(JSProtoKey)
1517 JS_IdToProtoKey(JSContext* cx, JS::HandleId id);
1520 * Returns the original value of |Function.prototype| from the global object in
1521 * which |forObj| was created.
1523 extern JS_PUBLIC_API(JSObject*)
1524 JS_GetFunctionPrototype(JSContext* cx, JS::HandleObject forObj);
1527 * Returns the original value of |Object.prototype| from the global object in
1528 * which |forObj| was created.
1530 extern JS_PUBLIC_API(JSObject*)
1531 JS_GetObjectPrototype(JSContext* cx, JS::HandleObject forObj);
1534 * Returns the original value of |Array.prototype| from the global object in
1535 * which |forObj| was created.
1537 extern JS_PUBLIC_API(JSObject*)
1538 JS_GetArrayPrototype(JSContext* cx, JS::HandleObject forObj);
1541 * Returns the original value of |Error.prototype| from the global
1542 * object of the current compartment of cx.
1544 extern JS_PUBLIC_API(JSObject*)
1545 JS_GetErrorPrototype(JSContext* cx);
1548 * Returns the %IteratorPrototype% object that all built-in iterator prototype
1549 * chains go through for the global object of the current compartment of cx.
1551 extern JS_PUBLIC_API(JSObject*)
1552 JS_GetIteratorPrototype(JSContext* cx);
1554 extern JS_PUBLIC_API(JSObject*)
1555 JS_GetGlobalForObject(JSContext* cx, JSObject* obj);
1557 extern JS_PUBLIC_API(bool)
1558 JS_IsGlobalObject(JSObject* obj);
1560 extern JS_PUBLIC_API(JSObject*)
1561 JS_GlobalLexicalScope(JSObject* obj);
1563 extern JS_PUBLIC_API(bool)
1564 JS_HasExtensibleLexicalScope(JSObject* obj);
1566 extern JS_PUBLIC_API(JSObject*)
1567 JS_ExtensibleLexicalScope(JSObject* obj);
1570 * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
1571 * or if |c|'s global has been collected.
1573 extern JS_PUBLIC_API(JSObject*)
1574 JS_GetGlobalForCompartmentOrNull(JSContext* cx, JSCompartment* c);
1576 namespace JS {
1578 extern JS_PUBLIC_API(JSObject*)
1579 CurrentGlobalOrNull(JSContext* cx);
1581 } // namespace JS
1584 * Add 'Reflect.parse', a SpiderMonkey extension, to the Reflect object on the
1585 * given global.
1587 extern JS_PUBLIC_API(bool)
1588 JS_InitReflectParse(JSContext* cx, JS::HandleObject global);
1591 * Add various profiling-related functions as properties of the given object.
1592 * Defined in builtin/Profilers.cpp.
1594 extern JS_PUBLIC_API(bool)
1595 JS_DefineProfilingFunctions(JSContext* cx, JS::HandleObject obj);
1597 /* Defined in vm/Debugger.cpp. */
1598 extern JS_PUBLIC_API(bool)
1599 JS_DefineDebuggerObject(JSContext* cx, JS::HandleObject obj);
1601 #ifdef JS_HAS_CTYPES
1603 * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
1604 * object will be sealed.
1606 extern JS_PUBLIC_API(bool)
1607 JS_InitCTypesClass(JSContext* cx, JS::HandleObject global);
1610 * Convert a unicode string 'source' of length 'slen' to the platform native
1611 * charset, returning a null-terminated string allocated with JS_malloc. On
1612 * failure, this function should report an error.
1614 typedef char*
1615 (* JSCTypesUnicodeToNativeFun)(JSContext* cx, const char16_t* source, size_t slen);
1618 * Set of function pointers that ctypes can use for various internal functions.
1619 * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
1620 * and will result in the applicable ctypes functionality not being available.
1622 struct JSCTypesCallbacks {
1623 JSCTypesUnicodeToNativeFun unicodeToNative;
1626 typedef struct JSCTypesCallbacks JSCTypesCallbacks;
1629 * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
1630 * pointer to static data that exists for the lifetime of 'ctypesObj', but it
1631 * may safely be altered after calling this function and without having
1632 * to call this function again.
1634 extern JS_PUBLIC_API(void)
1635 JS_SetCTypesCallbacks(JSObject* ctypesObj, const JSCTypesCallbacks* callbacks);
1636 #endif
1638 extern JS_PUBLIC_API(void*)
1639 JS_malloc(JSContext* cx, size_t nbytes);
1641 extern JS_PUBLIC_API(void*)
1642 JS_realloc(JSContext* cx, void* p, size_t oldBytes, size_t newBytes);
1645 * A wrapper for js_free(p) that may delay js_free(p) invocation as a
1646 * performance optimization.
1647 * cx may be nullptr.
1649 extern JS_PUBLIC_API(void)
1650 JS_free(JSContext* cx, void* p);
1653 * A wrapper for js_free(p) that may delay js_free(p) invocation as a
1654 * performance optimization as specified by the given JSFreeOp instance.
1656 extern JS_PUBLIC_API(void)
1657 JS_freeop(JSFreeOp* fop, void* p);
1659 extern JS_PUBLIC_API(JSFreeOp*)
1660 JS_GetDefaultFreeOp(JSRuntime* rt);
1662 extern JS_PUBLIC_API(void)
1663 JS_updateMallocCounter(JSContext* cx, size_t nbytes);
1665 extern JS_PUBLIC_API(char*)
1666 JS_strdup(JSContext* cx, const char* s);
1668 /** Duplicate a string. Does not report an error on failure. */
1669 extern JS_PUBLIC_API(char*)
1670 JS_strdup(JSRuntime* rt, const char* s);
1673 * Register externally maintained GC roots.
1675 * traceOp: the trace operation. For each root the implementation should call
1676 * JS_CallTracer whenever the root contains a traceable thing.
1677 * data: the data argument to pass to each invocation of traceOp.
1679 extern JS_PUBLIC_API(bool)
1680 JS_AddExtraGCRootsTracer(JSRuntime* rt, JSTraceDataOp traceOp, void* data);
1682 /** Undo a call to JS_AddExtraGCRootsTracer. */
1683 extern JS_PUBLIC_API(void)
1684 JS_RemoveExtraGCRootsTracer(JSRuntime* rt, JSTraceDataOp traceOp, void* data);
1687 * Garbage collector API.
1689 extern JS_PUBLIC_API(void)
1690 JS_GC(JSRuntime* rt);
1692 extern JS_PUBLIC_API(void)
1693 JS_MaybeGC(JSContext* cx);
1695 extern JS_PUBLIC_API(void)
1696 JS_SetGCCallback(JSRuntime* rt, JSGCCallback cb, void* data);
1698 extern JS_PUBLIC_API(void)
1699 JS_SetObjectsTenuredCallback(JSRuntime* rt, JSObjectsTenuredCallback cb,
1700 void* data);
1702 extern JS_PUBLIC_API(bool)
1703 JS_AddFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb, void* data);
1705 extern JS_PUBLIC_API(void)
1706 JS_RemoveFinalizeCallback(JSRuntime* rt, JSFinalizeCallback cb);
1709 * Weak pointers and garbage collection
1711 * Weak pointers are by their nature not marked as part of garbage collection,
1712 * but they may need to be updated in two cases after a GC:
1714 * 1) Their referent was found not to be live and is about to be finalized
1715 * 2) Their referent has been moved by a compacting GC
1717 * To handle this, any part of the system that maintain weak pointers to
1718 * JavaScript GC things must register a callback with
1719 * JS_(Add,Remove)WeakPointer{ZoneGroup,Compartment}Callback(). This callback
1720 * must then call JS_UpdateWeakPointerAfterGC() on all weak pointers it knows
1721 * about.
1723 * Since sweeping is incremental, we have several callbacks to avoid repeatedly
1724 * having to visit all embedder structures. The WeakPointerZoneGroupCallback is
1725 * called once for each strongly connected group of zones, whereas the
1726 * WeakPointerCompartmentCallback is called once for each compartment that is
1727 * visited while sweeping. Structures that cannot contain references in more
1728 * than one compartment should sweep the relevant per-compartment structures
1729 * using the latter callback to minimizer per-slice overhead.
1731 * The argument to JS_UpdateWeakPointerAfterGC() is an in-out param. If the
1732 * referent is about to be finalized the pointer will be set to null. If the
1733 * referent has been moved then the pointer will be updated to point to the new
1734 * location.
1736 * Callers of this method are responsible for updating any state that is
1737 * dependent on the object's address. For example, if the object's address is
1738 * used as a key in a hashtable, then the object must be removed and
1739 * re-inserted with the correct hash.
1742 extern JS_PUBLIC_API(bool)
1743 JS_AddWeakPointerZoneGroupCallback(JSRuntime* rt, JSWeakPointerZoneGroupCallback cb, void* data);
1745 extern JS_PUBLIC_API(void)
1746 JS_RemoveWeakPointerZoneGroupCallback(JSRuntime* rt, JSWeakPointerZoneGroupCallback cb);
1748 extern JS_PUBLIC_API(bool)
1749 JS_AddWeakPointerCompartmentCallback(JSRuntime* rt, JSWeakPointerCompartmentCallback cb,
1750 void* data);
1752 extern JS_PUBLIC_API(void)
1753 JS_RemoveWeakPointerCompartmentCallback(JSRuntime* rt, JSWeakPointerCompartmentCallback cb);
1755 extern JS_PUBLIC_API(void)
1756 JS_UpdateWeakPointerAfterGC(JS::Heap<JSObject*>* objp);
1758 extern JS_PUBLIC_API(void)
1759 JS_UpdateWeakPointerAfterGCUnbarriered(JSObject** objp);
1761 typedef enum JSGCParamKey {
1762 /** Maximum nominal heap before last ditch GC. */
1763 JSGC_MAX_BYTES = 0,
1765 /** Number of JS_malloc bytes before last ditch GC. */
1766 JSGC_MAX_MALLOC_BYTES = 1,
1768 /** Amount of bytes allocated by the GC. */
1769 JSGC_BYTES = 3,
1771 /** Number of times GC has been invoked. Includes both major and minor GC. */
1772 JSGC_NUMBER = 4,
1774 /** Select GC mode. */
1775 JSGC_MODE = 6,
1777 /** Number of cached empty GC chunks. */
1778 JSGC_UNUSED_CHUNKS = 7,
1780 /** Total number of allocated GC chunks. */
1781 JSGC_TOTAL_CHUNKS = 8,
1783 /** Max milliseconds to spend in an incremental GC slice. */
1784 JSGC_SLICE_TIME_BUDGET = 9,
1786 /** Maximum size the GC mark stack can grow to. */
1787 JSGC_MARK_STACK_LIMIT = 10,
1790 * GCs less than this far apart in time will be considered 'high-frequency GCs'.
1791 * See setGCLastBytes in jsgc.cpp.
1793 JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
1795 /** Start of dynamic heap growth. */
1796 JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
1798 /** End of dynamic heap growth. */
1799 JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
1801 /** Upper bound of heap growth. */
1802 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
1804 /** Lower bound of heap growth. */
1805 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
1807 /** Heap growth for low frequency GCs. */
1808 JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
1811 * If false, the heap growth factor is fixed at 3. If true, it is determined
1812 * based on whether GCs are high- or low- frequency.
1814 JSGC_DYNAMIC_HEAP_GROWTH = 17,
1816 /** If true, high-frequency GCs will use a longer mark slice. */
1817 JSGC_DYNAMIC_MARK_SLICE = 18,
1819 /** Lower limit after which we limit the heap growth. */
1820 JSGC_ALLOCATION_THRESHOLD = 19,
1823 * We decommit memory lazily. If more than this number of megabytes is
1824 * available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
1825 * to decommit it.
1827 JSGC_DECOMMIT_THRESHOLD = 20,
1830 * We try to keep at least this many unused chunks in the free chunk pool at
1831 * all times, even after a shrinking GC.
1833 JSGC_MIN_EMPTY_CHUNK_COUNT = 21,
1835 /** We never keep more than this many unused chunks in the free chunk pool. */
1836 JSGC_MAX_EMPTY_CHUNK_COUNT = 22,
1838 /** Whether compacting GC is enabled. */
1839 JSGC_COMPACTING_ENABLED = 23,
1841 /** If true, painting can trigger IGC slices. */
1842 JSGC_REFRESH_FRAME_SLICES_ENABLED = 24,
1843 } JSGCParamKey;
1845 extern JS_PUBLIC_API(void)
1846 JS_SetGCParameter(JSRuntime* rt, JSGCParamKey key, uint32_t value);
1848 extern JS_PUBLIC_API(uint32_t)
1849 JS_GetGCParameter(JSRuntime* rt, JSGCParamKey key);
1851 extern JS_PUBLIC_API(void)
1852 JS_SetGCParametersBasedOnAvailableMemory(JSRuntime* rt, uint32_t availMem);
1855 * Create a new JSString whose chars member refers to external memory, i.e.,
1856 * memory requiring application-specific finalization.
1858 extern JS_PUBLIC_API(JSString*)
1859 JS_NewExternalString(JSContext* cx, const char16_t* chars, size_t length,
1860 const JSStringFinalizer* fin);
1863 * Return whether 'str' was created with JS_NewExternalString or
1864 * JS_NewExternalStringWithClosure.
1866 extern JS_PUBLIC_API(bool)
1867 JS_IsExternalString(JSString* str);
1870 * Return the 'fin' arg passed to JS_NewExternalString.
1872 extern JS_PUBLIC_API(const JSStringFinalizer*)
1873 JS_GetExternalStringFinalizer(JSString* str);
1876 * Set the size of the native stack that should not be exceed. To disable
1877 * stack size checking pass 0.
1879 * SpiderMonkey allows for a distinction between system code (such as GCs, which
1880 * may incidentally be triggered by script but are not strictly performed on
1881 * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
1882 * and untrusted script. Each kind of code may have a different stack quota,
1883 * allowing embedders to keep higher-priority machinery running in the face of
1884 * scripted stack exhaustion by something else.
1886 * The stack quotas for each kind of code should be monotonically descending,
1887 * and may be specified with this function. If 0 is passed for a given kind
1888 * of code, it defaults to the value of the next-highest-priority kind.
1890 * This function may only be called immediately after the runtime is initialized
1891 * and before any code is executed and/or interrupts requested.
1893 extern JS_PUBLIC_API(void)
1894 JS_SetNativeStackQuota(JSRuntime* cx, size_t systemCodeStackSize,
1895 size_t trustedScriptStackSize = 0,
1896 size_t untrustedScriptStackSize = 0);
1898 /************************************************************************/
1900 extern JS_PUBLIC_API(bool)
1901 JS_ValueToId(JSContext* cx, JS::HandleValue v, JS::MutableHandleId idp);
1903 extern JS_PUBLIC_API(bool)
1904 JS_StringToId(JSContext* cx, JS::HandleString s, JS::MutableHandleId idp);
1906 extern JS_PUBLIC_API(bool)
1907 JS_IdToValue(JSContext* cx, jsid id, JS::MutableHandle<JS::Value> vp);
1909 namespace JS {
1912 * Convert obj to a primitive value. On success, store the result in vp and
1913 * return true.
1915 * The hint argument must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no
1916 * hint).
1918 * Implements: ES6 7.1.1 ToPrimitive(input, [PreferredType]).
1920 extern JS_PUBLIC_API(bool)
1921 ToPrimitive(JSContext* cx, JS::HandleObject obj, JSType hint, JS::MutableHandleValue vp);
1924 * If args.get(0) is one of the strings "string", "number", or "default", set
1925 * *result to JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID accordingly and
1926 * return true. Otherwise, return false with a TypeError pending.
1928 * This can be useful in implementing a @@toPrimitive method.
1930 extern JS_PUBLIC_API(bool)
1931 GetFirstArgumentAsTypeHint(JSContext* cx, CallArgs args, JSType *result);
1933 } /* namespace JS */
1935 extern JS_PUBLIC_API(bool)
1936 JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
1937 JS::MutableHandleValue vp);
1939 extern JS_PUBLIC_API(bool)
1940 JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
1941 JS::MutableHandleValue vp, JS::ObjectOpResult& result);
1943 template<typename T>
1944 struct JSConstScalarSpec {
1945 const char* name;
1946 T val;
1949 typedef JSConstScalarSpec<double> JSConstDoubleSpec;
1950 typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
1952 struct JSJitInfo;
1955 * Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will
1956 * allow us to pass one JSJitInfo per function with the property/function spec,
1957 * without additional field overhead.
1959 typedef struct JSNativeWrapper {
1960 JSNative op;
1961 const JSJitInfo* info;
1962 } JSNativeWrapper;
1965 * Macro static initializers which make it easy to pass no JSJitInfo as part of a
1966 * JSPropertySpec or JSFunctionSpec.
1968 #define JSNATIVE_WRAPPER(native) { {native, nullptr} }
1971 * Description of a property. JS_DefineProperties and JS_InitClass take arrays
1972 * of these and define many properties at once. JS_PSG, JS_PSGS and JS_PS_END
1973 * are helper macros for defining such arrays.
1975 struct JSPropertySpec {
1976 struct SelfHostedWrapper {
1977 void* unused;
1978 const char* funname;
1981 const char* name;
1982 uint8_t flags;
1983 union {
1984 JSNativeWrapper native;
1985 SelfHostedWrapper selfHosted;
1986 } getter;
1987 union {
1988 JSNativeWrapper native;
1989 SelfHostedWrapper selfHosted;
1990 } setter;
1992 bool isSelfHosted() const {
1993 #ifdef DEBUG
1994 // Verify that our accessors match our JSPROP_GETTER flag.
1995 if (flags & JSPROP_GETTER)
1996 checkAccessorsAreSelfHosted();
1997 else
1998 checkAccessorsAreNative();
1999 #endif
2000 return (flags & JSPROP_GETTER);
2003 static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper),
2004 "JSPropertySpec::getter/setter must be compact");
2005 static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info),
2006 "JS_SELF_HOSTED* macros below require that "
2007 "SelfHostedWrapper::funname overlay "
2008 "JSNativeWrapper::info");
2009 private:
2010 void checkAccessorsAreNative() const {
2011 MOZ_ASSERT(getter.native.op);
2012 // We may not have a setter at all. So all we can assert here, for the
2013 // native case is that if we have a jitinfo for the setter then we have
2014 // a setter op too. This is good enough to make sure we don't have a
2015 // SelfHostedWrapper for the setter.
2016 MOZ_ASSERT_IF(setter.native.info, setter.native.op);
2019 void checkAccessorsAreSelfHosted() const {
2020 MOZ_ASSERT(!getter.selfHosted.unused);
2021 MOZ_ASSERT(!setter.selfHosted.unused);
2025 namespace JS {
2026 namespace detail {
2028 /* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
2029 inline int CheckIsNative(JSNative native);
2031 /* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
2032 template<size_t N>
2033 inline int
2034 CheckIsCharacterLiteral(const char (&arr)[N]);
2036 /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */
2037 inline int CheckIsGetterOp(JSGetterOp op);
2039 /* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */
2040 inline int CheckIsSetterOp(JSSetterOp op);
2043 } // namespace detail
2044 } // namespace JS
2046 #define JS_CAST_NATIVE_TO(v, To) \
2047 (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
2048 reinterpret_cast<To>(v))
2050 #define JS_CAST_STRING_TO(s, To) \
2051 (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
2052 reinterpret_cast<To>(s))
2054 #define JS_CHECK_ACCESSOR_FLAGS(flags) \
2055 (static_cast<mozilla::EnableIf<((flags) & ~(JSPROP_ENUMERATE | JSPROP_PERMANENT)) == 0>::Type>(0), \
2056 (flags))
2058 #define JS_PROPERTYOP_GETTER(v) \
2059 (static_cast<void>(sizeof(JS::detail::CheckIsGetterOp(v))), \
2060 reinterpret_cast<JSNative>(v))
2062 #define JS_PROPERTYOP_SETTER(v) \
2063 (static_cast<void>(sizeof(JS::detail::CheckIsSetterOp(v))), \
2064 reinterpret_cast<JSNative>(v))
2066 #define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub)
2068 #define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
2071 * JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition
2072 * of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
2073 * them.
2075 #define JS_PSG(name, getter, flags) \
2076 {name, \
2077 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
2078 JSNATIVE_WRAPPER(getter), \
2079 JSNATIVE_WRAPPER(nullptr)}
2080 #define JS_PSGS(name, getter, setter, flags) \
2081 {name, \
2082 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
2083 JSNATIVE_WRAPPER(getter), \
2084 JSNATIVE_WRAPPER(setter)}
2085 #define JS_SELF_HOSTED_GET(name, getterName, flags) \
2086 {name, \
2087 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
2088 { { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) } }, \
2089 JSNATIVE_WRAPPER(nullptr) }
2090 #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
2091 {name, \
2092 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
2093 { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) }, \
2094 { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo*) } }
2095 #define JS_PS_END { nullptr, 0, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr) }
2096 #define JS_SELF_HOSTED_SYM_GET(symbol, getterName, flags) \
2097 {reinterpret_cast<const char*>(uint32_t(::JS::SymbolCode::symbol) + 1), \
2098 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
2099 { { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo*) } }, \
2100 JSNATIVE_WRAPPER(nullptr) }
2103 * To define a native function, set call to a JSNativeWrapper. To define a
2104 * self-hosted function, set selfHostedName to the name of a function
2105 * compiled during JSRuntime::initSelfHosting.
2107 struct JSFunctionSpec {
2108 const char* name;
2109 JSNativeWrapper call;
2110 uint16_t nargs;
2111 uint16_t flags;
2112 const char* selfHostedName;
2116 * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
2117 * that's passed to JS_DefineFunctions or JS_InitClass.
2119 #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
2122 * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
2123 * homage to the old JSNative/JSFastNative split) simply adds the flag
2124 * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
2125 * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function.
2126 * JS_INLINABLE_FN allows specifying an InlinableNative enum value for natives
2127 * inlined or specialized by the JIT. Finally JS_FNSPEC has slots for all the
2128 * fields.
2130 * The _SYM variants allow defining a function with a symbol key rather than a
2131 * string key. For example, use JS_SYM_FN(iterator, ...) to define an
2132 * @@iterator method.
2134 #define JS_FS(name,call,nargs,flags) \
2135 JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
2136 #define JS_FN(name,call,nargs,flags) \
2137 JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
2138 #define JS_INLINABLE_FN(name,call,nargs,flags,native) \
2139 JS_FNSPEC(name, call, &js::jit::JitInfo_##native, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
2140 #define JS_SYM_FN(symbol,call,nargs,flags) \
2141 JS_SYM_FNSPEC(symbol, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
2142 #define JS_FNINFO(name,call,info,nargs,flags) \
2143 JS_FNSPEC(name, call, info, nargs, flags, nullptr)
2144 #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
2145 JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
2146 #define JS_SELF_HOSTED_SYM_FN(symbol, selfHostedName, nargs, flags) \
2147 JS_SYM_FNSPEC(symbol, nullptr, nullptr, nargs, flags, selfHostedName)
2148 #define JS_SYM_FNSPEC(symbol, call, info, nargs, flags, selfHostedName) \
2149 JS_FNSPEC(reinterpret_cast<const char*>( \
2150 uint32_t(::JS::SymbolCode::symbol) + 1), \
2151 call, info, nargs, flags, selfHostedName)
2152 #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
2153 {name, {call, info}, nargs, flags, selfHostedName}
2155 extern JS_PUBLIC_API(JSObject*)
2156 JS_InitClass(JSContext* cx, JS::HandleObject obj, JS::HandleObject parent_proto,
2157 const JSClass* clasp, JSNative constructor, unsigned nargs,
2158 const JSPropertySpec* ps, const JSFunctionSpec* fs,
2159 const JSPropertySpec* static_ps, const JSFunctionSpec* static_fs);
2162 * Set up ctor.prototype = proto and proto.constructor = ctor with the
2163 * right property flags.
2165 extern JS_PUBLIC_API(bool)
2166 JS_LinkConstructorAndPrototype(JSContext* cx, JS::Handle<JSObject*> ctor,
2167 JS::Handle<JSObject*> proto);
2169 extern JS_PUBLIC_API(const JSClass*)
2170 JS_GetClass(JSObject* obj);
2172 extern JS_PUBLIC_API(bool)
2173 JS_InstanceOf(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp, JS::CallArgs* args);
2175 extern JS_PUBLIC_API(bool)
2176 JS_HasInstance(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool* bp);
2178 extern JS_PUBLIC_API(void*)
2179 JS_GetPrivate(JSObject* obj);
2181 extern JS_PUBLIC_API(void)
2182 JS_SetPrivate(JSObject* obj, void* data);
2184 extern JS_PUBLIC_API(void*)
2185 JS_GetInstancePrivate(JSContext* cx, JS::Handle<JSObject*> obj, const JSClass* clasp,
2186 JS::CallArgs* args);
2188 extern JS_PUBLIC_API(JSObject*)
2189 JS_GetConstructor(JSContext* cx, JS::Handle<JSObject*> proto);
2191 namespace JS {
2193 enum ZoneSpecifier {
2194 FreshZone = 0,
2195 SystemZone = 1
2199 * CompartmentCreationOptions specifies options relevant to creating a new
2200 * compartment, that are either immutable characteristics of that compartment
2201 * or that are discarded after the compartment has been created.
2203 * Access to these options on an existing compartment is read-only: if you
2204 * need particular selections, make them before you create the compartment.
2206 class JS_PUBLIC_API(CompartmentCreationOptions)
2208 public:
2209 CompartmentCreationOptions()
2210 : addonId_(nullptr),
2211 traceGlobal_(nullptr),
2212 invisibleToDebugger_(false),
2213 mergeable_(false),
2214 preserveJitCode_(false),
2215 cloneSingletons_(false),
2216 experimentalDateTimeFormatFormatToPartsEnabled_(false),
2217 sharedMemoryAndAtomics_(false),
2218 secureContext_(false)
2220 zone_.spec = JS::FreshZone;
2223 // A null add-on ID means that the compartment is not associated with an
2224 // add-on.
2225 JSAddonId* addonIdOrNull() const { return addonId_; }
2226 CompartmentCreationOptions& setAddonId(JSAddonId* id) {
2227 addonId_ = id;
2228 return *this;
2231 JSTraceOp getTrace() const {
2232 return traceGlobal_;
2234 CompartmentCreationOptions& setTrace(JSTraceOp op) {
2235 traceGlobal_ = op;
2236 return *this;
2239 void* zonePointer() const {
2240 MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
2241 return zone_.pointer;
2243 ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
2244 CompartmentCreationOptions& setZone(ZoneSpecifier spec);
2245 CompartmentCreationOptions& setSameZoneAs(JSObject* obj);
2247 // Certain scopes (i.e. XBL compilation scopes) are implementation details
2248 // of the embedding, and references to them should never leak out to script.
2249 // This flag causes the this compartment to skip firing onNewGlobalObject
2250 // and makes addDebuggee a no-op for this global.
2251 bool invisibleToDebugger() const { return invisibleToDebugger_; }
2252 CompartmentCreationOptions& setInvisibleToDebugger(bool flag) {
2253 invisibleToDebugger_ = flag;
2254 return *this;
2257 // Compartments used for off-thread compilation have their contents merged
2258 // into a target compartment when the compilation is finished. This is only
2259 // allowed if this flag is set. The invisibleToDebugger flag must also be
2260 // set for such compartments.
2261 bool mergeable() const { return mergeable_; }
2262 CompartmentCreationOptions& setMergeable(bool flag) {
2263 mergeable_ = flag;
2264 return *this;
2267 // Determines whether this compartment should preserve JIT code on
2268 // non-shrinking GCs.
2269 bool preserveJitCode() const { return preserveJitCode_; }
2270 CompartmentCreationOptions& setPreserveJitCode(bool flag) {
2271 preserveJitCode_ = flag;
2272 return *this;
2275 bool cloneSingletons() const { return cloneSingletons_; }
2276 CompartmentCreationOptions& setCloneSingletons(bool flag) {
2277 cloneSingletons_ = flag;
2278 return *this;
2281 // ECMA-402 is considering adding a "formatToParts" DateTimeFormat method,
2282 // that exposes not just a formatted string but its ordered subcomponents.
2283 // The method, its semantics, and its name are all well short of being
2284 // finalized, so for now it's exposed *only* if requested.
2286 // Until "formatToParts" is included in a final specification edition, it's
2287 // subject to change or removal at any time. Do *not* rely on it in
2288 // mission-critical code that can't be changed if ECMA-402 decides not to
2289 // accept the method in its current form.
2290 bool experimentalDateTimeFormatFormatToPartsEnabled() const {
2291 return experimentalDateTimeFormatFormatToPartsEnabled_;
2293 CompartmentCreationOptions& setExperimentalDateTimeFormatFormatToPartsEnabled(bool flag) {
2294 experimentalDateTimeFormatFormatToPartsEnabled_ = flag;
2295 return *this;
2298 bool getSharedMemoryAndAtomicsEnabled() const;
2299 CompartmentCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
2301 // This flag doesn't affect JS engine behavior. It is used by Gecko to
2302 // mark whether content windows and workers are "Secure Context"s. See
2303 // https://w3c.github.io/webappsec-secure-contexts/
2304 // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
2305 bool secureContext() const { return secureContext_; }
2306 CompartmentCreationOptions& setSecureContext(bool flag) {
2307 secureContext_ = flag;
2308 return *this;
2311 private:
2312 JSAddonId* addonId_;
2313 JSTraceOp traceGlobal_;
2314 union {
2315 ZoneSpecifier spec;
2316 void* pointer; // js::Zone* is not exposed in the API.
2317 } zone_;
2318 bool invisibleToDebugger_;
2319 bool mergeable_;
2320 bool preserveJitCode_;
2321 bool cloneSingletons_;
2322 bool experimentalDateTimeFormatFormatToPartsEnabled_;
2323 bool sharedMemoryAndAtomics_;
2324 bool secureContext_;
2328 * CompartmentBehaviors specifies behaviors of a compartment that can be
2329 * changed after the compartment's been created.
2331 class JS_PUBLIC_API(CompartmentBehaviors)
2333 public:
2334 class Override {
2335 public:
2336 Override() : mode_(Default) {}
2338 bool get(bool defaultValue) const {
2339 if (mode_ == Default)
2340 return defaultValue;
2341 return mode_ == ForceTrue;
2344 void set(bool overrideValue) {
2345 mode_ = overrideValue ? ForceTrue : ForceFalse;
2348 void reset() {
2349 mode_ = Default;
2352 private:
2353 enum Mode {
2354 Default,
2355 ForceTrue,
2356 ForceFalse
2359 Mode mode_;
2362 CompartmentBehaviors()
2363 : version_(JSVERSION_UNKNOWN)
2364 , discardSource_(false)
2365 , disableLazyParsing_(false)
2366 , singletonsAsTemplates_(true)
2370 JSVersion version() const { return version_; }
2371 CompartmentBehaviors& setVersion(JSVersion aVersion) {
2372 MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
2373 version_ = aVersion;
2374 return *this;
2377 // For certain globals, we know enough about the code that will run in them
2378 // that we can discard script source entirely.
2379 bool discardSource() const { return discardSource_; }
2380 CompartmentBehaviors& setDiscardSource(bool flag) {
2381 discardSource_ = flag;
2382 return *this;
2385 bool disableLazyParsing() const { return disableLazyParsing_; }
2386 CompartmentBehaviors& setDisableLazyParsing(bool flag) {
2387 disableLazyParsing_ = flag;
2388 return *this;
2391 bool extraWarnings(JSRuntime* rt) const;
2392 bool extraWarnings(JSContext* cx) const;
2393 Override& extraWarningsOverride() { return extraWarningsOverride_; }
2395 bool getSingletonsAsTemplates() const {
2396 return singletonsAsTemplates_;
2398 CompartmentBehaviors& setSingletonsAsValues() {
2399 singletonsAsTemplates_ = false;
2400 return *this;
2403 private:
2404 JSVersion version_;
2405 bool discardSource_;
2406 bool disableLazyParsing_;
2407 Override extraWarningsOverride_;
2409 // To XDR singletons, we need to ensure that all singletons are all used as
2410 // templates, by making JSOP_OBJECT return a clone of the JSScript
2411 // singleton, instead of returning the value which is baked in the JSScript.
2412 bool singletonsAsTemplates_;
2416 * CompartmentOptions specifies compartment characteristics: both those that
2417 * can't be changed on a compartment once it's been created
2418 * (CompartmentCreationOptions), and those that can be changed on an existing
2419 * compartment (CompartmentBehaviors).
2421 class JS_PUBLIC_API(CompartmentOptions)
2423 public:
2424 explicit CompartmentOptions()
2425 : creationOptions_(),
2426 behaviors_()
2429 CompartmentOptions(const CompartmentCreationOptions& compartmentCreation,
2430 const CompartmentBehaviors& compartmentBehaviors)
2431 : creationOptions_(compartmentCreation),
2432 behaviors_(compartmentBehaviors)
2435 // CompartmentCreationOptions specify fundamental compartment
2436 // characteristics that must be specified when the compartment is created,
2437 // that can't be changed after the compartment is created.
2438 CompartmentCreationOptions& creationOptions() {
2439 return creationOptions_;
2441 const CompartmentCreationOptions& creationOptions() const {
2442 return creationOptions_;
2445 // CompartmentBehaviors specify compartment characteristics that can be
2446 // changed after the compartment is created.
2447 CompartmentBehaviors& behaviors() {
2448 return behaviors_;
2450 const CompartmentBehaviors& behaviors() const {
2451 return behaviors_;
2454 private:
2455 CompartmentCreationOptions creationOptions_;
2456 CompartmentBehaviors behaviors_;
2459 JS_PUBLIC_API(const CompartmentCreationOptions&)
2460 CompartmentCreationOptionsRef(JSCompartment* compartment);
2462 JS_PUBLIC_API(const CompartmentCreationOptions&)
2463 CompartmentCreationOptionsRef(JSObject* obj);
2465 JS_PUBLIC_API(const CompartmentCreationOptions&)
2466 CompartmentCreationOptionsRef(JSContext* cx);
2468 JS_PUBLIC_API(CompartmentBehaviors&)
2469 CompartmentBehaviorsRef(JSCompartment* compartment);
2471 JS_PUBLIC_API(CompartmentBehaviors&)
2472 CompartmentBehaviorsRef(JSObject* obj);
2474 JS_PUBLIC_API(CompartmentBehaviors&)
2475 CompartmentBehaviorsRef(JSContext* cx);
2478 * During global creation, we fire notifications to callbacks registered
2479 * via the Debugger API. These callbacks are arbitrary script, and can touch
2480 * the global in arbitrary ways. When that happens, the global should not be
2481 * in a half-baked state. But this creates a problem for consumers that need
2482 * to set slots on the global to put it in a consistent state.
2484 * This API provides a way for consumers to set slots atomically (immediately
2485 * after the global is created), before any debugger hooks are fired. It's
2486 * unfortunately on the clunky side, but that's the way the cookie crumbles.
2488 * If callers have no additional state on the global to set up, they may pass
2489 * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
2490 * fire the hook as its final act before returning. Otherwise, callers should
2491 * pass |DontFireOnNewGlobalHook|, which means that they are responsible for
2492 * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
2493 * an error occurs and the operation aborts, callers should skip firing the
2494 * hook. But otherwise, callers must take care to fire the hook exactly once
2495 * before compiling any script in the global's scope (we have assertions in
2496 * place to enforce this). This lets us be sure that debugger clients never miss
2497 * breakpoints.
2499 enum OnNewGlobalHookOption {
2500 FireOnNewGlobalHook,
2501 DontFireOnNewGlobalHook
2504 } /* namespace JS */
2506 extern JS_PUBLIC_API(JSObject*)
2507 JS_NewGlobalObject(JSContext* cx, const JSClass* clasp, JSPrincipals* principals,
2508 JS::OnNewGlobalHookOption hookOption,
2509 const JS::CompartmentOptions& options);
2511 * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
2512 * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
2513 * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
2514 * object, from which we can be sure the compartment is relevant, and mark it.
2516 * It is still possible to specify custom trace hooks for global object classes. They can be
2517 * provided via the CompartmentOptions passed to JS_NewGlobalObject.
2519 extern JS_PUBLIC_API(void)
2520 JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global);
2522 extern JS_PUBLIC_API(void)
2523 JS_FireOnNewGlobalObject(JSContext* cx, JS::HandleObject global);
2525 extern JS_PUBLIC_API(JSObject*)
2526 JS_NewObject(JSContext* cx, const JSClass* clasp);
2528 extern JS_PUBLIC_API(bool)
2529 JS_IsNative(JSObject* obj);
2531 extern JS_PUBLIC_API(JSRuntime*)
2532 JS_GetObjectRuntime(JSObject* obj);
2535 * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
2536 * proto. If proto is nullptr, the JS object will have `null` as [[Prototype]].
2538 extern JS_PUBLIC_API(JSObject*)
2539 JS_NewObjectWithGivenProto(JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
2541 /** Creates a new plain object, like `new Object()`, with Object.prototype as [[Prototype]]. */
2542 extern JS_PUBLIC_API(JSObject*)
2543 JS_NewPlainObject(JSContext* cx);
2546 * Freeze obj, and all objects it refers to, recursively. This will not recurse
2547 * through non-extensible objects, on the assumption that those are already
2548 * deep-frozen.
2550 extern JS_PUBLIC_API(bool)
2551 JS_DeepFreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
2554 * Freezes an object; see ES5's Object.freeze(obj) method.
2556 extern JS_PUBLIC_API(bool)
2557 JS_FreezeObject(JSContext* cx, JS::Handle<JSObject*> obj);
2560 /*** Property descriptors ************************************************************************/
2562 namespace JS {
2564 struct PropertyDescriptor {
2565 JSObject* obj;
2566 unsigned attrs;
2567 JSGetterOp getter;
2568 JSSetterOp setter;
2569 JS::Value value;
2571 PropertyDescriptor()
2572 : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JS::UndefinedValue())
2575 static void trace(PropertyDescriptor* self, JSTracer* trc) { self->trace(trc); }
2576 void trace(JSTracer* trc);
2579 template <typename Outer>
2580 class PropertyDescriptorOperations
2582 const PropertyDescriptor& desc() const { return static_cast<const Outer*>(this)->get(); }
2584 bool has(unsigned bit) const {
2585 MOZ_ASSERT(bit != 0);
2586 MOZ_ASSERT((bit & (bit - 1)) == 0); // only a single bit
2587 return (desc().attrs & bit) != 0;
2590 bool hasAny(unsigned bits) const {
2591 return (desc().attrs & bits) != 0;
2594 bool hasAll(unsigned bits) const {
2595 return (desc().attrs & bits) == bits;
2598 // Non-API attributes bit used internally for arguments objects.
2599 enum { SHADOWABLE = JSPROP_INTERNAL_USE_BIT };
2601 public:
2602 // Descriptors with JSGetterOp/JSSetterOp are considered data
2603 // descriptors. It's complicated.
2604 bool isAccessorDescriptor() const { return hasAny(JSPROP_GETTER | JSPROP_SETTER); }
2605 bool isGenericDescriptor() const {
2606 return (desc().attrs&
2607 (JSPROP_GETTER | JSPROP_SETTER | JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE)) ==
2608 (JSPROP_IGNORE_READONLY | JSPROP_IGNORE_VALUE);
2610 bool isDataDescriptor() const { return !isAccessorDescriptor() && !isGenericDescriptor(); }
2612 bool hasConfigurable() const { return !has(JSPROP_IGNORE_PERMANENT); }
2613 bool configurable() const { MOZ_ASSERT(hasConfigurable()); return !has(JSPROP_PERMANENT); }
2615 bool hasEnumerable() const { return !has(JSPROP_IGNORE_ENUMERATE); }
2616 bool enumerable() const { MOZ_ASSERT(hasEnumerable()); return has(JSPROP_ENUMERATE); }
2618 bool hasValue() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_VALUE); }
2619 JS::HandleValue value() const {
2620 return JS::HandleValue::fromMarkedLocation(&desc().value);
2623 bool hasWritable() const { return !isAccessorDescriptor() && !has(JSPROP_IGNORE_READONLY); }
2624 bool writable() const { MOZ_ASSERT(hasWritable()); return !has(JSPROP_READONLY); }
2626 bool hasGetterObject() const { return has(JSPROP_GETTER); }
2627 JS::HandleObject getterObject() const {
2628 MOZ_ASSERT(hasGetterObject());
2629 return JS::HandleObject::fromMarkedLocation(
2630 reinterpret_cast<JSObject* const*>(&desc().getter));
2632 bool hasSetterObject() const { return has(JSPROP_SETTER); }
2633 JS::HandleObject setterObject() const {
2634 MOZ_ASSERT(hasSetterObject());
2635 return JS::HandleObject::fromMarkedLocation(
2636 reinterpret_cast<JSObject* const*>(&desc().setter));
2639 bool hasGetterOrSetter() const { return desc().getter || desc().setter; }
2640 bool isShared() const { return has(JSPROP_SHARED); }
2642 JS::HandleObject object() const {
2643 return JS::HandleObject::fromMarkedLocation(&desc().obj);
2645 unsigned attributes() const { return desc().attrs; }
2646 JSGetterOp getter() const { return desc().getter; }
2647 JSSetterOp setter() const { return desc().setter; }
2649 void assertValid() const {
2650 #ifdef DEBUG
2651 MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
2652 JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
2653 JSPROP_READONLY | JSPROP_IGNORE_READONLY |
2654 JSPROP_IGNORE_VALUE |
2655 JSPROP_GETTER |
2656 JSPROP_SETTER |
2657 JSPROP_SHARED |
2658 JSPROP_REDEFINE_NONCONFIGURABLE |
2659 JSPROP_RESOLVING |
2660 SHADOWABLE)) == 0);
2661 MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
2662 MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
2663 if (isAccessorDescriptor()) {
2664 MOZ_ASSERT(has(JSPROP_SHARED));
2665 MOZ_ASSERT(!has(JSPROP_READONLY));
2666 MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
2667 MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
2668 MOZ_ASSERT(!has(SHADOWABLE));
2669 MOZ_ASSERT(value().isUndefined());
2670 MOZ_ASSERT_IF(!has(JSPROP_GETTER), !getter());
2671 MOZ_ASSERT_IF(!has(JSPROP_SETTER), !setter());
2672 } else {
2673 MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
2674 MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
2676 MOZ_ASSERT(getter() != JS_PropertyStub);
2677 MOZ_ASSERT(setter() != JS_StrictPropertyStub);
2679 MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
2680 MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
2681 MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
2682 MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
2683 MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
2684 #endif
2687 void assertComplete() const {
2688 #ifdef DEBUG
2689 assertValid();
2690 MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
2691 JSPROP_PERMANENT |
2692 JSPROP_READONLY |
2693 JSPROP_GETTER |
2694 JSPROP_SETTER |
2695 JSPROP_SHARED |
2696 JSPROP_REDEFINE_NONCONFIGURABLE |
2697 JSPROP_RESOLVING |
2698 SHADOWABLE)) == 0);
2699 MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
2700 #endif
2703 void assertCompleteIfFound() const {
2704 #ifdef DEBUG
2705 if (object())
2706 assertComplete();
2707 #endif
2711 template <typename Outer>
2712 class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
2714 PropertyDescriptor& desc() { return static_cast<Outer*>(this)->get(); }
2716 public:
2717 void clear() {
2718 object().set(nullptr);
2719 setAttributes(0);
2720 setGetter(nullptr);
2721 setSetter(nullptr);
2722 value().setUndefined();
2725 void initFields(HandleObject obj, HandleValue v, unsigned attrs,
2726 JSGetterOp getterOp, JSSetterOp setterOp) {
2727 MOZ_ASSERT(getterOp != JS_PropertyStub);
2728 MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
2730 object().set(obj);
2731 value().set(v);
2732 setAttributes(attrs);
2733 setGetter(getterOp);
2734 setSetter(setterOp);
2737 void assign(PropertyDescriptor& other) {
2738 object().set(other.obj);
2739 setAttributes(other.attrs);
2740 setGetter(other.getter);
2741 setSetter(other.setter);
2742 value().set(other.value);
2745 void setDataDescriptor(HandleValue v, unsigned attrs) {
2746 MOZ_ASSERT((attrs & ~(JSPROP_ENUMERATE |
2747 JSPROP_PERMANENT |
2748 JSPROP_READONLY |
2749 JSPROP_IGNORE_ENUMERATE |
2750 JSPROP_IGNORE_PERMANENT |
2751 JSPROP_IGNORE_READONLY)) == 0);
2752 object().set(nullptr);
2753 setAttributes(attrs);
2754 setGetter(nullptr);
2755 setSetter(nullptr);
2756 value().set(v);
2759 JS::MutableHandleObject object() {
2760 return JS::MutableHandleObject::fromMarkedLocation(&desc().obj);
2762 unsigned& attributesRef() { return desc().attrs; }
2763 JSGetterOp& getter() { return desc().getter; }
2764 JSSetterOp& setter() { return desc().setter; }
2765 JS::MutableHandleValue value() {
2766 return JS::MutableHandleValue::fromMarkedLocation(&desc().value);
2768 void setValue(JS::HandleValue v) {
2769 MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
2770 attributesRef() &= ~JSPROP_IGNORE_VALUE;
2771 value().set(v);
2774 void setConfigurable(bool configurable) {
2775 setAttributes((desc().attrs & ~(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT)) |
2776 (configurable ? 0 : JSPROP_PERMANENT));
2778 void setEnumerable(bool enumerable) {
2779 setAttributes((desc().attrs & ~(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE)) |
2780 (enumerable ? JSPROP_ENUMERATE : 0));
2782 void setWritable(bool writable) {
2783 MOZ_ASSERT(!(desc().attrs & (JSPROP_GETTER | JSPROP_SETTER)));
2784 setAttributes((desc().attrs & ~(JSPROP_IGNORE_READONLY | JSPROP_READONLY)) |
2785 (writable ? 0 : JSPROP_READONLY));
2787 void setAttributes(unsigned attrs) { desc().attrs = attrs; }
2789 void setGetter(JSGetterOp op) {
2790 MOZ_ASSERT(op != JS_PropertyStub);
2791 desc().getter = op;
2793 void setSetter(JSSetterOp op) {
2794 MOZ_ASSERT(op != JS_StrictPropertyStub);
2795 desc().setter = op;
2797 void setGetterObject(JSObject* obj) {
2798 desc().getter = reinterpret_cast<JSGetterOp>(obj);
2799 desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
2800 desc().attrs |= JSPROP_GETTER | JSPROP_SHARED;
2802 void setSetterObject(JSObject* obj) {
2803 desc().setter = reinterpret_cast<JSSetterOp>(obj);
2804 desc().attrs &= ~(JSPROP_IGNORE_VALUE | JSPROP_IGNORE_READONLY | JSPROP_READONLY);
2805 desc().attrs |= JSPROP_SETTER | JSPROP_SHARED;
2808 JS::MutableHandleObject getterObject() {
2809 MOZ_ASSERT(this->hasGetterObject());
2810 return JS::MutableHandleObject::fromMarkedLocation(
2811 reinterpret_cast<JSObject**>(&desc().getter));
2813 JS::MutableHandleObject setterObject() {
2814 MOZ_ASSERT(this->hasSetterObject());
2815 return JS::MutableHandleObject::fromMarkedLocation(
2816 reinterpret_cast<JSObject**>(&desc().setter));
2820 } /* namespace JS */
2822 namespace js {
2824 template <>
2825 class RootedBase<JS::PropertyDescriptor>
2826 : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JS::PropertyDescriptor>>
2829 template <>
2830 class HandleBase<JS::PropertyDescriptor>
2831 : public JS::PropertyDescriptorOperations<JS::Handle<JS::PropertyDescriptor>>
2834 template <>
2835 class MutableHandleBase<JS::PropertyDescriptor>
2836 : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JS::PropertyDescriptor>>
2839 } /* namespace js */
2841 namespace JS {
2843 extern JS_PUBLIC_API(bool)
2844 ObjectToCompletePropertyDescriptor(JSContext* cx,
2845 JS::HandleObject obj,
2846 JS::HandleValue descriptor,
2847 JS::MutableHandle<PropertyDescriptor> desc);
2850 * ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc).
2852 * If desc.object() is null, then vp is set to undefined.
2854 extern JS_PUBLIC_API(bool)
2855 FromPropertyDescriptor(JSContext* cx,
2856 JS::Handle<JS::PropertyDescriptor> desc,
2857 JS::MutableHandleValue vp);
2859 } // namespace JS
2862 /*** Standard internal methods ********************************************************************
2864 * The functions below are the fundamental operations on objects.
2866 * ES6 specifies 14 internal methods that define how objects behave. The
2867 * standard is actually quite good on this topic, though you may have to read
2868 * it a few times. See ES6 sections 6.1.7.2 and 6.1.7.3.
2870 * When 'obj' is an ordinary object, these functions have boring standard
2871 * behavior as specified by ES6 section 9.1; see the section about internal
2872 * methods in js/src/vm/NativeObject.h.
2874 * Proxies override the behavior of internal methods. So when 'obj' is a proxy,
2875 * any one of the functions below could do just about anything. See
2876 * js/public/Proxy.h.
2880 * Get the prototype of obj, storing it in result.
2882 * Implements: ES6 [[GetPrototypeOf]] internal method.
2884 extern JS_PUBLIC_API(bool)
2885 JS_GetPrototype(JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject result);
2888 * If |obj| (underneath any functionally-transparent wrapper proxies) has as
2889 * its [[GetPrototypeOf]] trap the ordinary [[GetPrototypeOf]] behavior defined
2890 * for ordinary objects, set |*isOrdinary = true| and store |obj|'s prototype
2891 * in |result|. Otherwise set |*isOrdinary = false|. In case of error, both
2892 * outparams have unspecified value.
2894 extern JS_PUBLIC_API(bool)
2895 JS_GetPrototypeIfOrdinary(JSContext* cx, JS::HandleObject obj, bool* isOrdinary,
2896 JS::MutableHandleObject result);
2899 * Change the prototype of obj.
2901 * Implements: ES6 [[SetPrototypeOf]] internal method.
2903 * In cases where ES6 [[SetPrototypeOf]] returns false without an exception,
2904 * JS_SetPrototype throws a TypeError and returns false.
2906 * Performance warning: JS_SetPrototype is very bad for performance. It may
2907 * cause compiled jit-code to be invalidated. It also causes not only obj but
2908 * all other objects in the same "group" as obj to be permanently deoptimized.
2909 * It's better to create the object with the right prototype from the start.
2911 extern JS_PUBLIC_API(bool)
2912 JS_SetPrototype(JSContext* cx, JS::HandleObject obj, JS::HandleObject proto);
2915 * Determine whether obj is extensible. Extensible objects can have new
2916 * properties defined on them. Inextensible objects can't, and their
2917 * [[Prototype]] slot is fixed as well.
2919 * Implements: ES6 [[IsExtensible]] internal method.
2921 extern JS_PUBLIC_API(bool)
2922 JS_IsExtensible(JSContext* cx, JS::HandleObject obj, bool* extensible);
2925 * Attempt to make |obj| non-extensible.
2927 * Not all failures are treated as errors. See the comment on
2928 * JS::ObjectOpResult in js/public/Class.h.
2930 * Implements: ES6 [[PreventExtensions]] internal method.
2932 extern JS_PUBLIC_API(bool)
2933 JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, JS::ObjectOpResult& result);
2936 * Attempt to make the [[Prototype]] of |obj| immutable, such that any attempt
2937 * to modify it will fail. If an error occurs during the attempt, return false
2938 * (with a pending exception set, depending upon the nature of the error). If
2939 * no error occurs, return true with |*succeeded| set to indicate whether the
2940 * attempt successfully made the [[Prototype]] immutable.
2942 * This is a nonstandard internal method.
2944 extern JS_PUBLIC_API(bool)
2945 JS_SetImmutablePrototype(JSContext* cx, JS::HandleObject obj, bool* succeeded);
2948 * Get a description of one of obj's own properties. If no such property exists
2949 * on obj, return true with desc.object() set to null.
2951 * Implements: ES6 [[GetOwnProperty]] internal method.
2953 extern JS_PUBLIC_API(bool)
2954 JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
2955 JS::MutableHandle<JS::PropertyDescriptor> desc);
2957 extern JS_PUBLIC_API(bool)
2958 JS_GetOwnPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
2959 JS::MutableHandle<JS::PropertyDescriptor> desc);
2961 extern JS_PUBLIC_API(bool)
2962 JS_GetOwnUCPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char16_t* name,
2963 JS::MutableHandle<JS::PropertyDescriptor> desc);
2966 * Like JS_GetOwnPropertyDescriptorById, but also searches the prototype chain
2967 * if no own property is found directly on obj. The object on which the
2968 * property is found is returned in desc.object(). If the property is not found
2969 * on the prototype chain, this returns true with desc.object() set to null.
2971 extern JS_PUBLIC_API(bool)
2972 JS_GetPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
2973 JS::MutableHandle<JS::PropertyDescriptor> desc);
2975 extern JS_PUBLIC_API(bool)
2976 JS_GetPropertyDescriptor(JSContext* cx, JS::HandleObject obj, const char* name,
2977 JS::MutableHandle<JS::PropertyDescriptor> desc);
2980 * Define a property on obj.
2982 * This function uses JS::ObjectOpResult to indicate conditions that ES6
2983 * specifies as non-error failures. This is inconvenient at best, so use this
2984 * function only if you are implementing a proxy handler's defineProperty()
2985 * method. For all other purposes, use one of the many DefineProperty functions
2986 * below that throw an exception in all failure cases.
2988 * Implements: ES6 [[DefineOwnProperty]] internal method.
2990 extern JS_PUBLIC_API(bool)
2991 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
2992 JS::Handle<JS::PropertyDescriptor> desc,
2993 JS::ObjectOpResult& result);
2996 * Define a property on obj, throwing a TypeError if the attempt fails.
2997 * This is the C++ equivalent of `Object.defineProperty(obj, id, desc)`.
2999 extern JS_PUBLIC_API(bool)
3000 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
3001 JS::Handle<JS::PropertyDescriptor> desc);
3003 extern JS_PUBLIC_API(bool)
3004 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
3005 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3007 extern JS_PUBLIC_API(bool)
3008 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
3009 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3011 extern JS_PUBLIC_API(bool)
3012 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
3013 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3015 extern JS_PUBLIC_API(bool)
3016 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
3017 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3019 extern JS_PUBLIC_API(bool)
3020 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
3021 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3023 extern JS_PUBLIC_API(bool)
3024 JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value,
3025 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3027 extern JS_PUBLIC_API(bool)
3028 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value,
3029 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3031 extern JS_PUBLIC_API(bool)
3032 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
3033 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3035 extern JS_PUBLIC_API(bool)
3036 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value,
3037 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3039 extern JS_PUBLIC_API(bool)
3040 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value,
3041 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3043 extern JS_PUBLIC_API(bool)
3044 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value,
3045 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3047 extern JS_PUBLIC_API(bool)
3048 JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value,
3049 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3051 extern JS_PUBLIC_API(bool)
3052 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3053 JS::Handle<JS::PropertyDescriptor> desc,
3054 JS::ObjectOpResult& result);
3056 extern JS_PUBLIC_API(bool)
3057 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3058 JS::Handle<JS::PropertyDescriptor> desc);
3060 extern JS_PUBLIC_API(bool)
3061 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3062 JS::HandleValue value, unsigned attrs,
3063 JSNative getter = nullptr, JSNative setter = nullptr);
3065 extern JS_PUBLIC_API(bool)
3066 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3067 JS::HandleObject value, unsigned attrs,
3068 JSNative getter = nullptr, JSNative setter = nullptr);
3070 extern JS_PUBLIC_API(bool)
3071 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3072 JS::HandleString value, unsigned attrs,
3073 JSNative getter = nullptr, JSNative setter = nullptr);
3075 extern JS_PUBLIC_API(bool)
3076 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3077 int32_t value, unsigned attrs,
3078 JSNative getter = nullptr, JSNative setter = nullptr);
3080 extern JS_PUBLIC_API(bool)
3081 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3082 uint32_t value, unsigned attrs,
3083 JSNative getter = nullptr, JSNative setter = nullptr);
3085 extern JS_PUBLIC_API(bool)
3086 JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3087 double value, unsigned attrs,
3088 JSNative getter = nullptr, JSNative setter = nullptr);
3090 extern JS_PUBLIC_API(bool)
3091 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
3092 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3094 extern JS_PUBLIC_API(bool)
3095 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,
3096 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3098 extern JS_PUBLIC_API(bool)
3099 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString value,
3100 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3102 extern JS_PUBLIC_API(bool)
3103 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t value,
3104 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3106 extern JS_PUBLIC_API(bool)
3107 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t value,
3108 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3110 extern JS_PUBLIC_API(bool)
3111 JS_DefineElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double value,
3112 unsigned attrs, JSNative getter = nullptr, JSNative setter = nullptr);
3115 * Compute the expression `id in obj`.
3117 * If obj has an own or inherited property obj[id], set *foundp = true and
3118 * return true. If not, set *foundp = false and return true. On error, return
3119 * false with an exception pending.
3121 * Implements: ES6 [[Has]] internal method.
3123 extern JS_PUBLIC_API(bool)
3124 JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
3126 extern JS_PUBLIC_API(bool)
3127 JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
3129 extern JS_PUBLIC_API(bool)
3130 JS_HasUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3131 bool* vp);
3133 extern JS_PUBLIC_API(bool)
3134 JS_HasElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
3137 * Determine whether obj has an own property with the key `id`.
3139 * Implements: ES6 7.3.11 HasOwnProperty(O, P).
3141 extern JS_PUBLIC_API(bool)
3142 JS_HasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
3144 extern JS_PUBLIC_API(bool)
3145 JS_HasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
3148 * Get the value of the property `obj[id]`, or undefined if no such property
3149 * exists. This is the C++ equivalent of `vp = Reflect.get(obj, id, receiver)`.
3151 * Most callers don't need the `receiver` argument. Consider using
3152 * JS_GetProperty instead. (But if you're implementing a proxy handler's set()
3153 * method, it's often correct to call this function and pass the receiver
3154 * through.)
3156 * Implements: ES6 [[Get]] internal method.
3158 extern JS_PUBLIC_API(bool)
3159 JS_ForwardGetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
3160 JS::HandleValue receiver, JS::MutableHandleValue vp);
3162 extern JS_PUBLIC_API(bool)
3163 JS_ForwardGetElementTo(JSContext* cx, JS::HandleObject obj, uint32_t index,
3164 JS::HandleObject receiver, JS::MutableHandleValue vp);
3167 * Get the value of the property `obj[id]`, or undefined if no such property
3168 * exists. The result is stored in vp.
3170 * Implements: ES6 7.3.1 Get(O, P).
3172 extern JS_PUBLIC_API(bool)
3173 JS_GetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
3174 JS::MutableHandleValue vp);
3176 extern JS_PUBLIC_API(bool)
3177 JS_GetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::MutableHandleValue vp);
3179 extern JS_PUBLIC_API(bool)
3180 JS_GetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3181 JS::MutableHandleValue vp);
3183 extern JS_PUBLIC_API(bool)
3184 JS_GetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
3187 * Perform the same property assignment as `Reflect.set(obj, id, v, receiver)`.
3189 * This function has a `receiver` argument that most callers don't need.
3190 * Consider using JS_SetProperty instead.
3192 * Implements: ES6 [[Set]] internal method.
3194 extern JS_PUBLIC_API(bool)
3195 JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
3196 JS::HandleValue receiver, JS::ObjectOpResult& result);
3199 * Perform the assignment `obj[id] = v`.
3201 * This function performs non-strict assignment, so if the property is
3202 * read-only, nothing happens and no error is thrown.
3204 extern JS_PUBLIC_API(bool)
3205 JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
3207 extern JS_PUBLIC_API(bool)
3208 JS_SetProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue v);
3210 extern JS_PUBLIC_API(bool)
3211 JS_SetUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3212 JS::HandleValue v);
3214 extern JS_PUBLIC_API(bool)
3215 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
3217 extern JS_PUBLIC_API(bool)
3218 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
3220 extern JS_PUBLIC_API(bool)
3221 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
3223 extern JS_PUBLIC_API(bool)
3224 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, int32_t v);
3226 extern JS_PUBLIC_API(bool)
3227 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, uint32_t v);
3229 extern JS_PUBLIC_API(bool)
3230 JS_SetElement(JSContext* cx, JS::HandleObject obj, uint32_t index, double v);
3233 * Delete a property. This is the C++ equivalent of
3234 * `result = Reflect.deleteProperty(obj, id)`.
3236 * This function has a `result` out parameter that most callers don't need.
3237 * Unless you can pass through an ObjectOpResult provided by your caller, it's
3238 * probably best to use the JS_DeletePropertyById signature with just 3
3239 * arguments.
3241 * Implements: ES6 [[Delete]] internal method.
3243 extern JS_PUBLIC_API(bool)
3244 JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
3245 JS::ObjectOpResult& result);
3247 extern JS_PUBLIC_API(bool)
3248 JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name,
3249 JS::ObjectOpResult& result);
3251 extern JS_PUBLIC_API(bool)
3252 JS_DeleteUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, size_t namelen,
3253 JS::ObjectOpResult& result);
3255 extern JS_PUBLIC_API(bool)
3256 JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index, JS::ObjectOpResult& result);
3259 * Delete a property, ignoring strict failures. This is the C++ equivalent of
3260 * the JS `delete obj[id]` in non-strict mode code.
3262 extern JS_PUBLIC_API(bool)
3263 JS_DeletePropertyById(JSContext* cx, JS::HandleObject obj, jsid id);
3265 extern JS_PUBLIC_API(bool)
3266 JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name);
3268 extern JS_PUBLIC_API(bool)
3269 JS_DeleteElement(JSContext* cx, JS::HandleObject obj, uint32_t index);
3272 * Get an array of the non-symbol enumerable properties of obj.
3273 * This function is roughly equivalent to:
3275 * var result = [];
3276 * for (key in obj)
3277 * result.push(key);
3278 * return result;
3280 * This is the closest thing we currently have to the ES6 [[Enumerate]]
3281 * internal method.
3283 * The JSIdArray returned by JS_Enumerate must be rooted to protect its
3284 * contents from garbage collection. Use JS::AutoIdArray.
3286 extern JS_PUBLIC_API(bool)
3287 JS_Enumerate(JSContext* cx, JS::HandleObject obj, JS::MutableHandle<JS::IdVector> props);
3290 * API for determining callability and constructability. [[Call]] and
3291 * [[Construct]] are internal methods that aren't present on all objects, so it
3292 * is useful to ask if they are there or not. The standard itself asks these
3293 * questions routinely.
3295 namespace JS {
3298 * Return true if the given object is callable. In ES6 terms, an object is
3299 * callable if it has a [[Call]] internal method.
3301 * Implements: ES6 7.2.3 IsCallable(argument).
3303 * Functions are callable. A scripted proxy or wrapper is callable if its
3304 * target is callable. Most other objects aren't callable.
3306 extern JS_PUBLIC_API(bool)
3307 IsCallable(JSObject* obj);
3310 * Return true if the given object is a constructor. In ES6 terms, an object is
3311 * a constructor if it has a [[Construct]] internal method. The expression
3312 * `new obj()` throws a TypeError if obj is not a constructor.
3314 * Implements: ES6 7.2.4 IsConstructor(argument).
3316 * JS functions and classes are constructors. Arrow functions and most builtin
3317 * functions are not. A scripted proxy or wrapper is a constructor if its
3318 * target is a constructor.
3320 extern JS_PUBLIC_API(bool)
3321 IsConstructor(JSObject* obj);
3323 } /* namespace JS */
3326 * Call a function, passing a this-value and arguments. This is the C++
3327 * equivalent of `rval = Reflect.apply(fun, obj, args)`.
3329 * Implements: ES6 7.3.12 Call(F, V, [argumentsList]).
3330 * Use this function to invoke the [[Call]] internal method.
3332 extern JS_PUBLIC_API(bool)
3333 JS_CallFunctionValue(JSContext* cx, JS::HandleObject obj, JS::HandleValue fval,
3334 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3336 extern JS_PUBLIC_API(bool)
3337 JS_CallFunction(JSContext* cx, JS::HandleObject obj, JS::HandleFunction fun,
3338 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3341 * Perform the method call `rval = obj[name](args)`.
3343 extern JS_PUBLIC_API(bool)
3344 JS_CallFunctionName(JSContext* cx, JS::HandleObject obj, const char* name,
3345 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3347 namespace JS {
3349 static inline bool
3350 Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleFunction fun,
3351 const JS::HandleValueArray& args, MutableHandleValue rval)
3353 return !!JS_CallFunction(cx, thisObj, fun, args, rval);
3356 static inline bool
3357 Call(JSContext* cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
3358 MutableHandleValue rval)
3360 return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
3363 static inline bool
3364 Call(JSContext* cx, JS::HandleObject thisObj, const char* name, const JS::HandleValueArray& args,
3365 MutableHandleValue rval)
3367 return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
3370 extern JS_PUBLIC_API(bool)
3371 Call(JSContext* cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
3372 MutableHandleValue rval);
3374 static inline bool
3375 Call(JSContext* cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
3376 MutableHandleValue rval)
3378 MOZ_ASSERT(funObj);
3379 JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
3380 return Call(cx, thisv, fun, args, rval);
3384 * Invoke a constructor. This is the C++ equivalent of
3385 * `rval = Reflect.construct(fun, args, newTarget)`.
3387 * JS::Construct() takes a `newTarget` argument that most callers don't need.
3388 * Consider using the four-argument Construct signature instead. (But if you're
3389 * implementing a subclass or a proxy handler's construct() method, this is the
3390 * right function to call.)
3392 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]).
3393 * Use this function to invoke the [[Construct]] internal method.
3395 extern JS_PUBLIC_API(bool)
3396 Construct(JSContext* cx, JS::HandleValue fun, HandleObject newTarget,
3397 const JS::HandleValueArray &args, MutableHandleObject objp);
3400 * Invoke a constructor. This is the C++ equivalent of
3401 * `rval = new fun(...args)`.
3403 * Implements: ES6 7.3.13 Construct(F, [argumentsList], [newTarget]), when
3404 * newTarget is omitted.
3406 extern JS_PUBLIC_API(bool)
3407 Construct(JSContext* cx, JS::HandleValue fun, const JS::HandleValueArray& args,
3408 MutableHandleObject objp);
3410 } /* namespace JS */
3413 * Invoke a constructor, like the JS expression `new ctor(...args)`. Returns
3414 * the new object, or null on error.
3416 extern JS_PUBLIC_API(JSObject*)
3417 JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
3420 /*** Other property-defining functions ***********************************************************/
3422 extern JS_PUBLIC_API(JSObject*)
3423 JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name,
3424 const JSClass* clasp = nullptr, unsigned attrs = 0);
3426 extern JS_PUBLIC_API(bool)
3427 JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds);
3429 extern JS_PUBLIC_API(bool)
3430 JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis);
3432 extern JS_PUBLIC_API(bool)
3433 JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps);
3436 /* * */
3438 extern JS_PUBLIC_API(bool)
3439 JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
3440 bool* foundp);
3442 extern JS_PUBLIC_API(bool)
3443 JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name,
3444 bool* foundp);
3446 extern JS_PUBLIC_API(bool)
3447 JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name,
3448 size_t namelen, bool* foundp);
3450 extern JS_PUBLIC_API(bool)
3451 JS_AlreadyHasOwnElement(JSContext* cx, JS::HandleObject obj, uint32_t index, bool* foundp);
3453 extern JS_PUBLIC_API(JSObject*)
3454 JS_NewArrayObject(JSContext* cx, const JS::HandleValueArray& contents);
3456 extern JS_PUBLIC_API(JSObject*)
3457 JS_NewArrayObject(JSContext* cx, size_t length);
3460 * Returns true and sets |*isArray| indicating whether |value| is an Array
3461 * object or a wrapper around one, otherwise returns false on failure.
3463 * This method returns true with |*isArray == false| when passed a proxy whose
3464 * target is an Array, or when passed a revoked proxy.
3466 extern JS_PUBLIC_API(bool)
3467 JS_IsArrayObject(JSContext* cx, JS::HandleValue value, bool* isArray);
3470 * Returns true and sets |*isArray| indicating whether |obj| is an Array object
3471 * or a wrapper around one, otherwise returns false on failure.
3473 * This method returns true with |*isArray == false| when passed a proxy whose
3474 * target is an Array, or when passed a revoked proxy.
3476 extern JS_PUBLIC_API(bool)
3477 JS_IsArrayObject(JSContext* cx, JS::HandleObject obj, bool* isArray);
3479 extern JS_PUBLIC_API(bool)
3480 JS_GetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t* lengthp);
3482 extern JS_PUBLIC_API(bool)
3483 JS_SetArrayLength(JSContext* cx, JS::Handle<JSObject*> obj, uint32_t length);
3486 * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
3487 * done for all slots, regardless of the associated property descriptor.
3489 JS_PUBLIC_API(void)
3490 JS_SetAllNonReservedSlotsToUndefined(JSContext* cx, JSObject* objArg);
3493 * Create a new array buffer with the given contents. It must be legal to pass
3494 * these contents to free(). On success, the ownership is transferred to the
3495 * new array buffer.
3497 extern JS_PUBLIC_API(JSObject*)
3498 JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
3501 * Create a new array buffer with the given contents. The array buffer does not take ownership of
3502 * contents, and JS_DetachArrayBuffer must be called before the contents are disposed of.
3504 extern JS_PUBLIC_API(JSObject*)
3505 JS_NewArrayBufferWithExternalContents(JSContext* cx, size_t nbytes, void* contents);
3508 * Steal the contents of the given array buffer. The array buffer has its
3509 * length set to 0 and its contents array cleared. The caller takes ownership
3510 * of the return value and must free it or transfer ownership via
3511 * JS_NewArrayBufferWithContents when done using it.
3513 extern JS_PUBLIC_API(void*)
3514 JS_StealArrayBufferContents(JSContext* cx, JS::HandleObject obj);
3517 * Create a new mapped array buffer with the given memory mapped contents. It
3518 * must be legal to free the contents pointer by unmapping it. On success,
3519 * ownership is transferred to the new mapped array buffer.
3521 extern JS_PUBLIC_API(JSObject*)
3522 JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* contents);
3525 * Create memory mapped array buffer contents.
3526 * Caller must take care of closing fd after calling this function.
3528 extern JS_PUBLIC_API(void*)
3529 JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
3532 * Release the allocated resource of mapped array buffer contents before the
3533 * object is created.
3534 * If a new object has been created by JS_NewMappedArrayBufferWithContents()
3535 * with this content, then JS_DetachArrayBuffer() should be used instead to
3536 * release the resource used by the object.
3538 extern JS_PUBLIC_API(void)
3539 JS_ReleaseMappedArrayBufferContents(void* contents, size_t length);
3541 extern JS_PUBLIC_API(JS::Value)
3542 JS_GetReservedSlot(JSObject* obj, uint32_t index);
3544 extern JS_PUBLIC_API(void)
3545 JS_SetReservedSlot(JSObject* obj, uint32_t index, JS::Value v);
3548 /************************************************************************/
3551 * Functions and scripts.
3553 extern JS_PUBLIC_API(JSFunction*)
3554 JS_NewFunction(JSContext* cx, JSNative call, unsigned nargs, unsigned flags,
3555 const char* name);
3557 namespace JS {
3559 extern JS_PUBLIC_API(JSFunction*)
3560 GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id,
3561 unsigned nargs);
3564 * Create a new function based on the given JSFunctionSpec, *fs.
3565 * id is the result of a successful call to
3566 * `PropertySpecNameToPermanentId(cx, fs->name, &id)`.
3568 * Unlike JS_DefineFunctions, this does not treat fs as an array.
3569 * *fs must not be JS_FS_END.
3571 extern JS_PUBLIC_API(JSFunction*)
3572 NewFunctionFromSpec(JSContext* cx, const JSFunctionSpec* fs, HandleId id);
3574 } /* namespace JS */
3576 extern JS_PUBLIC_API(JSObject*)
3577 JS_GetFunctionObject(JSFunction* fun);
3580 * Return the function's identifier as a JSString, or null if fun is unnamed.
3581 * The returned string lives as long as fun, so you don't need to root a saved
3582 * reference to it if fun is well-connected or rooted, and provided you bound
3583 * the use of the saved reference by fun's lifetime.
3585 extern JS_PUBLIC_API(JSString*)
3586 JS_GetFunctionId(JSFunction* fun);
3589 * Return a function's display name. This is the defined name if one was given
3590 * where the function was defined, or it could be an inferred name by the JS
3591 * engine in the case that the function was defined to be anonymous. This can
3592 * still return nullptr if a useful display name could not be inferred. The
3593 * same restrictions on rooting as those in JS_GetFunctionId apply.
3595 extern JS_PUBLIC_API(JSString*)
3596 JS_GetFunctionDisplayId(JSFunction* fun);
3599 * Return the arity (length) of fun.
3601 extern JS_PUBLIC_API(uint16_t)
3602 JS_GetFunctionArity(JSFunction* fun);
3605 * Infallible predicate to test whether obj is a function object (faster than
3606 * comparing obj's class name to "Function", but equivalent unless someone has
3607 * overwritten the "Function" identifier with a different constructor and then
3608 * created instances using that constructor that might be passed in as obj).
3610 extern JS_PUBLIC_API(bool)
3611 JS_ObjectIsFunction(JSContext* cx, JSObject* obj);
3613 extern JS_PUBLIC_API(bool)
3614 JS_IsNativeFunction(JSObject* funobj, JSNative call);
3616 /** Return whether the given function is a valid constructor. */
3617 extern JS_PUBLIC_API(bool)
3618 JS_IsConstructor(JSFunction* fun);
3620 extern JS_PUBLIC_API(bool)
3621 JS_DefineFunctions(JSContext* cx, JS::Handle<JSObject*> obj, const JSFunctionSpec* fs);
3623 extern JS_PUBLIC_API(JSFunction*)
3624 JS_DefineFunction(JSContext* cx, JS::Handle<JSObject*> obj, const char* name, JSNative call,
3625 unsigned nargs, unsigned attrs);
3627 extern JS_PUBLIC_API(JSFunction*)
3628 JS_DefineUCFunction(JSContext* cx, JS::Handle<JSObject*> obj,
3629 const char16_t* name, size_t namelen, JSNative call,
3630 unsigned nargs, unsigned attrs);
3632 extern JS_PUBLIC_API(JSFunction*)
3633 JS_DefineFunctionById(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
3634 unsigned nargs, unsigned attrs);
3636 namespace JS {
3639 * Clone a top-level function into cx's global. This function will dynamically
3640 * fail if funobj was lexically nested inside some other function.
3642 extern JS_PUBLIC_API(JSObject*)
3643 CloneFunctionObject(JSContext* cx, HandleObject funobj);
3646 * As above, but providing an explicit scope chain. scopeChain must not include
3647 * the global object on it; that's implicit. It needs to contain the other
3648 * objects that should end up on the clone's scope chain.
3650 extern JS_PUBLIC_API(JSObject*)
3651 CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeChain);
3653 } // namespace JS
3656 * Given a buffer, return false if the buffer might become a valid
3657 * javascript statement with the addition of more lines. Otherwise return
3658 * true. The intent is to support interactive compilation - accumulate
3659 * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
3660 * the compiler.
3662 extern JS_PUBLIC_API(bool)
3663 JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle<JSObject*> obj, const char* utf8,
3664 size_t length);
3667 * |script| will always be set. On failure, it will be set to nullptr.
3669 extern JS_PUBLIC_API(bool)
3670 JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
3671 const JS::CompileOptions& options,
3672 JS::MutableHandleScript script);
3675 * |script| will always be set. On failure, it will be set to nullptr.
3677 extern JS_PUBLIC_API(bool)
3678 JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length,
3679 const JS::CompileOptions& options,
3680 JS::MutableHandleScript script);
3682 extern JS_PUBLIC_API(JSObject*)
3683 JS_GetGlobalFromScript(JSScript* script);
3685 extern JS_PUBLIC_API(const char*)
3686 JS_GetScriptFilename(JSScript* script);
3688 extern JS_PUBLIC_API(unsigned)
3689 JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
3691 extern JS_PUBLIC_API(JSScript*)
3692 JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun);
3694 namespace JS {
3696 /* Options for JavaScript compilation. */
3699 * In the most common use case, a CompileOptions instance is allocated on the
3700 * stack, and holds non-owning references to non-POD option values: strings;
3701 * principals; objects; and so on. The code declaring the instance guarantees
3702 * that such option values will outlive the CompileOptions itself: objects are
3703 * otherwise rooted; principals have had their reference counts bumped; strings
3704 * will not be freed until the CompileOptions goes out of scope. In this
3705 * situation, CompileOptions only refers to things others own, so it can be
3706 * lightweight.
3708 * In some cases, however, we need to hold compilation options with a
3709 * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
3710 * compilation options where a worker thread can find them, and then return
3711 * immediately. The worker thread will come along at some later point, and use
3712 * the options.
3714 * The compiler itself just needs to be able to access a collection of options;
3715 * it doesn't care who owns them, or what's keeping them alive. It does its own
3716 * addrefs/copies/tracing/etc.
3718 * Furthermore, in some cases compile options are propagated from one entity to
3719 * another (e.g. from a scriipt to a function defined in that script). This
3720 * involves copying over some, but not all, of the options.
3722 * So, we have a class hierarchy that reflects these four use cases:
3724 * - TransitiveCompileOptions is the common base class, representing options
3725 * that should get propagated from a script to functions defined in that
3726 * script. This is never instantiated directly.
3728 * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions,
3729 * representing a full set of compile options. It can be used by code that
3730 * simply needs to access options set elsewhere, like the compiler. This,
3731 * again, is never instantiated directly.
3733 * - The usual CompileOptions class must be stack-allocated, and holds
3734 * non-owning references to the filename, element, and so on. It's derived
3735 * from ReadOnlyCompileOptions, so the compiler can use it.
3737 * - OwningCompileOptions roots / copies / reference counts of all its values,
3738 * and unroots / frees / releases them when it is destructed. It too is
3739 * derived from ReadOnlyCompileOptions, so the compiler accepts it.
3742 enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger };
3745 * The common base class for the CompileOptions hierarchy.
3747 * Use this in code that needs to propagate compile options from one compilation
3748 * unit to another.
3750 class JS_FRIEND_API(TransitiveCompileOptions)
3752 protected:
3753 // The Web Platform allows scripts to be loaded from arbitrary cross-origin
3754 // sources. This allows an attack by which a malicious website loads a
3755 // sensitive file (say, a bank statement) cross-origin (using the user's
3756 // cookies), and sniffs the generated syntax errors (via a window.onerror
3757 // handler) for juicy morsels of its contents.
3759 // To counter this attack, HTML5 specifies that script errors should be
3760 // sanitized ("muted") when the script is not same-origin with the global
3761 // for which it is loaded. Callers should set this flag for cross-origin
3762 // scripts, and it will be propagated appropriately to child scripts and
3763 // passed back in JSErrorReports.
3764 bool mutedErrors_;
3765 const char* filename_;
3766 const char* introducerFilename_;
3767 const char16_t* sourceMapURL_;
3769 // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
3770 // is unusable until that's set to something more specific; the derived
3771 // classes' constructors take care of that, in ways appropriate to their
3772 // purpose.
3773 TransitiveCompileOptions()
3774 : mutedErrors_(false),
3775 filename_(nullptr),
3776 introducerFilename_(nullptr),
3777 sourceMapURL_(nullptr),
3778 version(JSVERSION_UNKNOWN),
3779 versionSet(false),
3780 utf8(false),
3781 selfHostingMode(false),
3782 canLazilyParse(true),
3783 strictOption(false),
3784 extraWarningsOption(false),
3785 werrorOption(false),
3786 asmJSOption(AsmJSOption::Disabled),
3787 throwOnAsmJSValidationFailureOption(false),
3788 forceAsync(false),
3789 installedFile(false),
3790 sourceIsLazy(false),
3791 introductionType(nullptr),
3792 introductionLineno(0),
3793 introductionOffset(0),
3794 hasIntroductionInfo(false)
3797 // Set all POD options (those not requiring reference counts, copies,
3798 // rooting, or other hand-holding) to their values in |rhs|.
3799 void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs);
3801 public:
3802 // Read-only accessors for non-POD options. The proper way to set these
3803 // depends on the derived type.
3804 bool mutedErrors() const { return mutedErrors_; }
3805 const char* filename() const { return filename_; }
3806 const char* introducerFilename() const { return introducerFilename_; }
3807 const char16_t* sourceMapURL() const { return sourceMapURL_; }
3808 virtual JSObject* element() const = 0;
3809 virtual JSString* elementAttributeName() const = 0;
3810 virtual JSScript* introductionScript() const = 0;
3812 // POD options.
3813 JSVersion version;
3814 bool versionSet;
3815 bool utf8;
3816 bool selfHostingMode;
3817 bool canLazilyParse;
3818 bool strictOption;
3819 bool extraWarningsOption;
3820 bool werrorOption;
3821 AsmJSOption asmJSOption;
3822 bool throwOnAsmJSValidationFailureOption;
3823 bool forceAsync;
3824 bool installedFile; // 'true' iff pre-compiling js file in packaged app
3825 bool sourceIsLazy;
3827 // |introductionType| is a statically allocated C string:
3828 // one of "eval", "Function", or "GeneratorFunction".
3829 const char* introductionType;
3830 unsigned introductionLineno;
3831 uint32_t introductionOffset;
3832 bool hasIntroductionInfo;
3834 private:
3835 void operator=(const TransitiveCompileOptions&) = delete;
3839 * The class representing a full set of compile options.
3841 * Use this in code that only needs to access compilation options created
3842 * elsewhere, like the compiler. Don't instantiate this class (the constructor
3843 * is protected anyway); instead, create instances only of the derived classes:
3844 * CompileOptions and OwningCompileOptions.
3846 class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions
3848 friend class CompileOptions;
3850 protected:
3851 ReadOnlyCompileOptions()
3852 : TransitiveCompileOptions(),
3853 lineno(1),
3854 column(0),
3855 isRunOnce(false),
3856 forEval(false),
3857 noScriptRval(false)
3860 // Set all POD options (those not requiring reference counts, copies,
3861 // rooting, or other hand-holding) to their values in |rhs|.
3862 void copyPODOptions(const ReadOnlyCompileOptions& rhs);
3864 public:
3865 // Read-only accessors for non-POD options. The proper way to set these
3866 // depends on the derived type.
3867 bool mutedErrors() const { return mutedErrors_; }
3868 const char* filename() const { return filename_; }
3869 const char* introducerFilename() const { return introducerFilename_; }
3870 const char16_t* sourceMapURL() const { return sourceMapURL_; }
3871 virtual JSObject* element() const = 0;
3872 virtual JSString* elementAttributeName() const = 0;
3873 virtual JSScript* introductionScript() const = 0;
3875 // POD options.
3876 unsigned lineno;
3877 unsigned column;
3878 // isRunOnce only applies to non-function scripts.
3879 bool isRunOnce;
3880 bool forEval;
3881 bool noScriptRval;
3883 private:
3884 void operator=(const ReadOnlyCompileOptions&) = delete;
3888 * Compilation options, with dynamic lifetime. An instance of this type
3889 * makes a copy of / holds / roots all dynamically allocated resources
3890 * (principals; elements; strings) that it refers to. Its destructor frees
3891 * / drops / unroots them. This is heavier than CompileOptions, below, but
3892 * unlike CompileOptions, it can outlive any given stack frame.
3894 * Note that this *roots* any JS values it refers to - they're live
3895 * unconditionally. Thus, instances of this type can't be owned, directly
3896 * or indirectly, by a JavaScript object: if any value that this roots ever
3897 * comes to refer to the object that owns this, then the whole cycle, and
3898 * anything else it entrains, will never be freed.
3900 class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
3902 JSRuntime* runtime;
3903 PersistentRootedObject elementRoot;
3904 PersistentRootedString elementAttributeNameRoot;
3905 PersistentRootedScript introductionScriptRoot;
3907 public:
3908 // A minimal constructor, for use with OwningCompileOptions::copy. This
3909 // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
3910 // shouldn't be used until we've set that to something real (as |copy|
3911 // will).
3912 explicit OwningCompileOptions(JSContext* cx);
3913 ~OwningCompileOptions();
3915 JSObject* element() const override { return elementRoot; }
3916 JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
3917 JSScript* introductionScript() const override { return introductionScriptRoot; }
3919 // Set this to a copy of |rhs|. Return false on OOM.
3920 bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs);
3922 /* These setters make copies of their string arguments, and are fallible. */
3923 bool setFile(JSContext* cx, const char* f);
3924 bool setFileAndLine(JSContext* cx, const char* f, unsigned l);
3925 bool setSourceMapURL(JSContext* cx, const char16_t* s);
3926 bool setIntroducerFilename(JSContext* cx, const char* s);
3928 /* These setters are infallible, and can be chained. */
3929 OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; }
3930 OwningCompileOptions& setElement(JSObject* e) {
3931 elementRoot = e;
3932 return *this;
3934 OwningCompileOptions& setElementAttributeName(JSString* p) {
3935 elementAttributeNameRoot = p;
3936 return *this;
3938 OwningCompileOptions& setIntroductionScript(JSScript* s) {
3939 introductionScriptRoot = s;
3940 return *this;
3942 OwningCompileOptions& setMutedErrors(bool mute) {
3943 mutedErrors_ = mute;
3944 return *this;
3946 OwningCompileOptions& setVersion(JSVersion v) {
3947 version = v;
3948 versionSet = true;
3949 return *this;
3951 OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
3952 OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; }
3953 OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
3954 OwningCompileOptions& setForEval(bool eval) { forEval = eval; return *this; }
3955 OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
3956 OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
3957 OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
3958 OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
3959 OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
3960 bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro,
3961 unsigned line, JSScript* script, uint32_t offset)
3963 if (!setIntroducerFilename(cx, introducerFn))
3964 return false;
3965 introductionType = intro;
3966 introductionLineno = line;
3967 introductionScriptRoot = script;
3968 introductionOffset = offset;
3969 hasIntroductionInfo = true;
3970 return true;
3973 private:
3974 void operator=(const CompileOptions& rhs) = delete;
3978 * Compilation options stored on the stack. An instance of this type
3979 * simply holds references to dynamically allocated resources (element;
3980 * filename; source map URL) that are owned by something else. If you
3981 * create an instance of this type, it's up to you to guarantee that
3982 * everything you store in it will outlive it.
3984 class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOptions
3986 RootedObject elementRoot;
3987 RootedString elementAttributeNameRoot;
3988 RootedScript introductionScriptRoot;
3990 public:
3991 explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN);
3992 CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs)
3993 : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
3994 introductionScriptRoot(cx)
3996 copyPODOptions(rhs);
3998 filename_ = rhs.filename();
3999 introducerFilename_ = rhs.introducerFilename();
4000 sourceMapURL_ = rhs.sourceMapURL();
4001 elementRoot = rhs.element();
4002 elementAttributeNameRoot = rhs.elementAttributeName();
4003 introductionScriptRoot = rhs.introductionScript();
4006 CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs)
4007 : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
4008 introductionScriptRoot(cx)
4010 copyPODTransitiveOptions(rhs);
4012 filename_ = rhs.filename();
4013 introducerFilename_ = rhs.introducerFilename();
4014 sourceMapURL_ = rhs.sourceMapURL();
4015 elementRoot = rhs.element();
4016 elementAttributeNameRoot = rhs.elementAttributeName();
4017 introductionScriptRoot = rhs.introductionScript();
4020 JSObject* element() const override { return elementRoot; }
4021 JSString* elementAttributeName() const override { return elementAttributeNameRoot; }
4022 JSScript* introductionScript() const override { return introductionScriptRoot; }
4024 CompileOptions& setFile(const char* f) { filename_ = f; return *this; }
4025 CompileOptions& setLine(unsigned l) { lineno = l; return *this; }
4026 CompileOptions& setFileAndLine(const char* f, unsigned l) {
4027 filename_ = f; lineno = l; return *this;
4029 CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; }
4030 CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; }
4031 CompileOptions& setElementAttributeName(JSString* p) {
4032 elementAttributeNameRoot = p;
4033 return *this;
4035 CompileOptions& setIntroductionScript(JSScript* s) {
4036 introductionScriptRoot = s;
4037 return *this;
4039 CompileOptions& setMutedErrors(bool mute) {
4040 mutedErrors_ = mute;
4041 return *this;
4043 CompileOptions& setVersion(JSVersion v) {
4044 version = v;
4045 versionSet = true;
4046 return *this;
4048 CompileOptions& setUTF8(bool u) { utf8 = u; return *this; }
4049 CompileOptions& setColumn(unsigned c) { column = c; return *this; }
4050 CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; }
4051 CompileOptions& setForEval(bool eval) { forEval = eval; return *this; }
4052 CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
4053 CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
4054 CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
4055 CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
4056 CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; }
4057 CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro,
4058 unsigned line, JSScript* script, uint32_t offset)
4060 introducerFilename_ = introducerFn;
4061 introductionType = intro;
4062 introductionLineno = line;
4063 introductionScriptRoot = script;
4064 introductionOffset = offset;
4065 hasIntroductionInfo = true;
4066 return *this;
4068 CompileOptions& maybeMakeStrictMode(bool strict) {
4069 strictOption = strictOption || strict;
4070 return *this;
4073 private:
4074 void operator=(const CompileOptions& rhs) = delete;
4078 * |script| will always be set. On failure, it will be set to nullptr.
4080 extern JS_PUBLIC_API(bool)
4081 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
4082 SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
4084 extern JS_PUBLIC_API(bool)
4085 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
4086 const char* bytes, size_t length, JS::MutableHandleScript script);
4088 extern JS_PUBLIC_API(bool)
4089 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
4090 const char16_t* chars, size_t length, JS::MutableHandleScript script);
4092 extern JS_PUBLIC_API(bool)
4093 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
4094 FILE* file, JS::MutableHandleScript script);
4096 extern JS_PUBLIC_API(bool)
4097 Compile(JSContext* cx, const ReadOnlyCompileOptions& options,
4098 const char* filename, JS::MutableHandleScript script);
4100 extern JS_PUBLIC_API(bool)
4101 CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
4102 SourceBufferHolder& srcBuf, JS::MutableHandleScript script);
4104 extern JS_PUBLIC_API(bool)
4105 CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
4106 const char* bytes, size_t length, JS::MutableHandleScript script);
4108 extern JS_PUBLIC_API(bool)
4109 CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
4110 const char16_t* chars, size_t length, JS::MutableHandleScript script);
4112 extern JS_PUBLIC_API(bool)
4113 CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
4114 FILE* file, JS::MutableHandleScript script);
4116 extern JS_PUBLIC_API(bool)
4117 CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options,
4118 const char* filename, JS::MutableHandleScript script);
4120 extern JS_PUBLIC_API(bool)
4121 CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length);
4124 * Off thread compilation control flow.
4126 * After successfully triggering an off thread compile of a script, the
4127 * callback will eventually be invoked with the specified data and a token
4128 * for the compilation. The callback will be invoked while off the main thread,
4129 * so must ensure that its operations are thread safe. Afterwards,
4130 * FinishOffThreadScript must be invoked on the main thread to get the result
4131 * script or nullptr. If maybecx is not specified, the resources will be freed,
4132 * but no script will be returned.
4134 * The characters passed in to CompileOffThread must remain live until the
4135 * callback is invoked, and the resulting script will be rooted until the call
4136 * to FinishOffThreadScript.
4139 extern JS_PUBLIC_API(bool)
4140 CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options,
4141 const char16_t* chars, size_t length,
4142 OffThreadCompileCallback callback, void* callbackData);
4144 extern JS_PUBLIC_API(JSScript*)
4145 FinishOffThreadScript(JSContext* maybecx, JSRuntime* rt, void* token);
4147 extern JS_PUBLIC_API(bool)
4148 CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
4149 const char16_t* chars, size_t length,
4150 OffThreadCompileCallback callback, void* callbackData);
4152 extern JS_PUBLIC_API(JSObject*)
4153 FinishOffThreadModule(JSContext* maybecx, JSRuntime* rt, void* token);
4156 * Compile a function with scopeChain plus the global as its scope chain.
4157 * scopeChain must contain objects in the current compartment of cx. The actual
4158 * scope chain used for the function will consist of With wrappers for those
4159 * objects, followed by the current global of the compartment cx is in. This
4160 * global must not be explicitly included in the scope chain.
4162 extern JS_PUBLIC_API(bool)
4163 CompileFunction(JSContext* cx, AutoObjectVector& scopeChain,
4164 const ReadOnlyCompileOptions& options,
4165 const char* name, unsigned nargs, const char* const* argnames,
4166 const char16_t* chars, size_t length, JS::MutableHandleFunction fun);
4169 * Same as above, but taking a SourceBufferHolder for the function body.
4171 extern JS_PUBLIC_API(bool)
4172 CompileFunction(JSContext* cx, AutoObjectVector& scopeChain,
4173 const ReadOnlyCompileOptions& options,
4174 const char* name, unsigned nargs, const char* const* argnames,
4175 SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun);
4178 * Same as above, but taking a const char * for the function body.
4180 extern JS_PUBLIC_API(bool)
4181 CompileFunction(JSContext* cx, AutoObjectVector& scopeChain,
4182 const ReadOnlyCompileOptions& options,
4183 const char* name, unsigned nargs, const char* const* argnames,
4184 const char* bytes, size_t length, JS::MutableHandleFunction fun);
4186 } /* namespace JS */
4188 extern JS_PUBLIC_API(JSString*)
4189 JS_DecompileScript(JSContext* cx, JS::Handle<JSScript*> script, const char* name, unsigned indent);
4192 * API extension: OR this into indent to avoid pretty-printing the decompiled
4193 * source resulting from JS_DecompileFunction.
4195 #define JS_DONT_PRETTY_PRINT ((unsigned)0x8000)
4197 extern JS_PUBLIC_API(JSString*)
4198 JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> fun, unsigned indent);
4202 * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either
4203 * they use the global as the scope, or they take an AutoObjectVector of objects
4204 * to use as the scope chain. In the former case, the global is also used as
4205 * the "this" keyword value and the variables object (ECMA parlance for where
4206 * 'var' and 'function' bind names) of the execution context for script. In the
4207 * latter case, the first object in the provided list is used, unless the list
4208 * is empty, in which case the global is used.
4210 * Why a runtime option? The alternative is to add APIs duplicating those
4211 * for the other value of flags, and that doesn't seem worth the code bloat
4212 * cost. Such new entry points would probably have less obvious names, too, so
4213 * would not tend to be used. The RuntimeOptionsRef adjustment, OTOH, can be
4214 * more easily hacked into existing code that does not depend on the bug; such
4215 * code can continue to use the familiar JS::Evaluate, etc., entry points.
4219 * Evaluate a script in the scope of the current global of cx.
4221 extern JS_PUBLIC_API(bool)
4222 JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval);
4224 extern JS_PUBLIC_API(bool)
4225 JS_ExecuteScript(JSContext* cx, JS::HandleScript script);
4228 * As above, but providing an explicit scope chain. scopeChain must not include
4229 * the global object on it; that's implicit. It needs to contain the other
4230 * objects that should end up on the script's scope chain.
4232 extern JS_PUBLIC_API(bool)
4233 JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& scopeChain,
4234 JS::HandleScript script, JS::MutableHandleValue rval);
4236 extern JS_PUBLIC_API(bool)
4237 JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& scopeChain, JS::HandleScript script);
4239 namespace JS {
4242 * Like the above, but handles a cross-compartment script. If the script is
4243 * cross-compartment, it is cloned into the current compartment before executing.
4245 extern JS_PUBLIC_API(bool)
4246 CloneAndExecuteScript(JSContext* cx, JS::Handle<JSScript*> script);
4248 } /* namespace JS */
4250 namespace JS {
4253 * Evaluate the given source buffer in the scope of the current global of cx.
4255 extern JS_PUBLIC_API(bool)
4256 Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
4257 SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
4260 * As above, but providing an explicit scope chain. scopeChain must not include
4261 * the global object on it; that's implicit. It needs to contain the other
4262 * objects that should end up on the script's scope chain.
4264 extern JS_PUBLIC_API(bool)
4265 Evaluate(JSContext* cx, AutoObjectVector& scopeChain, const ReadOnlyCompileOptions& options,
4266 SourceBufferHolder& srcBuf, JS::MutableHandleValue rval);
4269 * Evaluate the given character buffer in the scope of the current global of cx.
4271 extern JS_PUBLIC_API(bool)
4272 Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
4273 const char16_t* chars, size_t length, JS::MutableHandleValue rval);
4276 * As above, but providing an explicit scope chain. scopeChain must not include
4277 * the global object on it; that's implicit. It needs to contain the other
4278 * objects that should end up on the script's scope chain.
4280 extern JS_PUBLIC_API(bool)
4281 Evaluate(JSContext* cx, AutoObjectVector& scopeChain, const ReadOnlyCompileOptions& options,
4282 const char16_t* chars, size_t length, JS::MutableHandleValue rval);
4285 * Evaluate the given byte buffer in the scope of the current global of cx.
4287 extern JS_PUBLIC_API(bool)
4288 Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
4289 const char* bytes, size_t length, JS::MutableHandleValue rval);
4292 * Evaluate the given file in the scope of the current global of cx.
4294 extern JS_PUBLIC_API(bool)
4295 Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
4296 const char* filename, JS::MutableHandleValue rval);
4299 * Get the HostResolveImportedModule hook for a global.
4301 extern JS_PUBLIC_API(JSFunction*)
4302 GetModuleResolveHook(JSContext* cx);
4305 * Set the HostResolveImportedModule hook for a global to the given function.
4307 extern JS_PUBLIC_API(void)
4308 SetModuleResolveHook(JSContext* cx, JS::HandleFunction func);
4311 * Parse the given source buffer as a module in the scope of the current global
4312 * of cx and return a source text module record.
4314 extern JS_PUBLIC_API(bool)
4315 CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
4316 SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
4319 * Set the [[HostDefined]] field of a source text module record to the given
4320 * value.
4322 extern JS_PUBLIC_API(void)
4323 SetModuleHostDefinedField(JSObject* module, JS::Value value);
4326 * Get the [[HostDefined]] field of a source text module record.
4328 extern JS_PUBLIC_API(JS::Value)
4329 GetModuleHostDefinedField(JSObject* module);
4332 * Perform the ModuleDeclarationInstantiation operation on on the give source
4333 * text module record.
4335 * This transitively resolves all module dependencies (calling the
4336 * HostResolveImportedModule hook) and initializes the environment record for
4337 * the module.
4339 extern JS_PUBLIC_API(bool)
4340 ModuleDeclarationInstantiation(JSContext* cx, JS::HandleObject moduleRecord);
4343 * Perform the ModuleEvaluation operation on on the give source text module
4344 * record.
4346 * This does nothing if this module has already been evaluated. Otherwise, it
4347 * transitively evaluates all dependences of this module and then evaluates this
4348 * module.
4350 * ModuleDeclarationInstantiation must have completed prior to calling this.
4352 extern JS_PUBLIC_API(bool)
4353 ModuleEvaluation(JSContext* cx, JS::HandleObject moduleRecord);
4356 * Get a list of the module specifiers used by a source text module
4357 * record to request importation of modules.
4359 * The result is a JavaScript array of string values. ForOfIterator can be used
4360 * to extract the individual strings.
4362 extern JS_PUBLIC_API(JSObject*)
4363 GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
4366 * Get the script associated with a module.
4368 extern JS_PUBLIC_API(JSScript*)
4369 GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord);
4371 } /* namespace JS */
4373 extern JS_PUBLIC_API(bool)
4374 JS_CheckForInterrupt(JSContext* cx);
4377 * These functions allow setting an interrupt callback that will be called
4378 * from the JS thread some time after any thread triggered the callback using
4379 * JS_RequestInterruptCallback(rt).
4381 * To schedule the GC and for other activities the engine internally triggers
4382 * interrupt callbacks. The embedding should thus not rely on callbacks being
4383 * triggered through the external API only.
4385 * Important note: Additional callbacks can occur inside the callback handler
4386 * if it re-enters the JS engine. The embedding must ensure that the callback
4387 * is disconnected before attempting such re-entry.
4389 extern JS_PUBLIC_API(JSInterruptCallback)
4390 JS_SetInterruptCallback(JSRuntime* rt, JSInterruptCallback callback);
4392 extern JS_PUBLIC_API(JSInterruptCallback)
4393 JS_GetInterruptCallback(JSRuntime* rt);
4395 extern JS_PUBLIC_API(void)
4396 JS_RequestInterruptCallback(JSRuntime* rt);
4398 namespace JS {
4401 * Sets the callback that's invoked whenever a Promise job should be enqeued.
4403 * SpiderMonkey doesn't schedule Promise resolution jobs itself; instead,
4404 * using this function the embedding can provide a callback to do that
4405 * scheduling. The provided `callback` is invoked with the promise job
4406 * and the `data` pointer passed here as arguments.
4408 extern JS_PUBLIC_API(void)
4409 SetEnqueuePromiseJobCallback(JSRuntime* rt, JSEnqueuePromiseJobCallback callback,
4410 void* data = nullptr);
4413 * Returns a new instance of the Promise builtin class in the current
4414 * compartment, with the right slot layout. If a `proto` is passed, that gets
4415 * set as the instance's [[Prototype]] instead of the original value of
4416 * `Promise.prototype`.
4418 extern JS_PUBLIC_API(JSObject*)
4419 NewPromiseObject(JSContext* cx, JS::HandleObject executor, JS::HandleObject proto = nullptr);
4422 * Returns true if the given object is an unwrapped PromiseObject, false
4423 * otherwise.
4425 extern JS_PUBLIC_API(bool)
4426 IsPromiseObject(JS::HandleObject obj);
4429 * Returns the current compartment's original Promise constructor.
4431 extern JS_PUBLIC_API(JSObject*)
4432 GetPromiseConstructor(JSContext* cx);
4435 * Returns the current compartment's original Promise.prototype.
4437 extern JS_PUBLIC_API(JSObject*)
4438 GetPromisePrototype(JSContext* cx);
4440 // Keep this in sync with the PROMISE_STATE defines in SelfHostingDefines.h.
4441 enum class PromiseState {
4442 Pending,
4443 Fulfilled,
4444 Rejected
4448 * Returns the given Promise's state as a JS::PromiseState enum value.
4450 extern JS_PUBLIC_API(PromiseState)
4451 GetPromiseState(JS::HandleObject promise);
4454 * Returns the given Promise's process-unique ID.
4456 JS_PUBLIC_API(double)
4457 GetPromiseID(JS::HandleObject promise);
4460 * Returns the given Promise's result: either the resolution value for
4461 * fulfilled promises, or the rejection reason for rejected ones.
4463 extern JS_PUBLIC_API(JS::Value)
4464 GetPromiseResult(JS::HandleObject promise);
4467 * Returns a js::SavedFrame linked list of the stack that lead to the given
4468 * Promise's allocation.
4470 extern JS_PUBLIC_API(JSObject*)
4471 GetPromiseAllocationSite(JS::HandleObject promise);
4473 extern JS_PUBLIC_API(JSObject*)
4474 GetPromiseResolutionSite(JS::HandleObject promise);
4477 * Calls the current compartment's original Promise.resolve on the original
4478 * Promise constructor, with `resolutionValue` passed as an argument.
4480 extern JS_PUBLIC_API(JSObject*)
4481 CallOriginalPromiseResolve(JSContext* cx, JS::HandleValue resolutionValue);
4484 * Calls the current compartment's original Promise.reject on the original
4485 * Promise constructor, with `resolutionValue` passed as an argument.
4487 extern JS_PUBLIC_API(JSObject*)
4488 CallOriginalPromiseReject(JSContext* cx, JS::HandleValue rejectionValue);
4491 * Resolves the given Promise with the given `resolutionValue`.
4493 * Calls the `resolve` function that was passed to the executor function when
4494 * the Promise was created.
4496 extern JS_PUBLIC_API(bool)
4497 ResolvePromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue resolutionValue);
4500 * Rejects the given `promise` with the given `rejectionValue`.
4502 * Calls the `reject` function that was passed to the executor function when
4503 * the Promise was created.
4505 extern JS_PUBLIC_API(bool)
4506 RejectPromise(JSContext* cx, JS::HandleObject promise, JS::HandleValue rejectionValue);
4509 * Calls the current compartment's original Promise.prototype.then on the
4510 * given `promise`, with `onResolve` and `onReject` passed as arguments.
4512 * Asserts if the passed-in `promise` object isn't an unwrapped instance of
4513 * `Promise` or a subclass or `onResolve` and `onReject` aren't both either
4514 * `nullptr` or callable objects.
4516 extern JS_PUBLIC_API(JSObject*)
4517 CallOriginalPromiseThen(JSContext* cx, JS::HandleObject promise,
4518 JS::HandleObject onResolve, JS::HandleObject onReject);
4521 * Unforgeable, optimized version of the JS builtin Promise.prototype.then.
4523 * Takes a Promise instance and `onResolve`, `onReject` callables to enqueue
4524 * as reactions for that promise. In difference to Promise.prototype.then,
4525 * this doesn't create and return a new Promise instance.
4527 * Asserts if the passed-in `promise` object isn't an unwrapped instance of
4528 * `Promise` or a subclass or `onResolve` and `onReject` aren't both callable
4529 * objects.
4531 extern JS_PUBLIC_API(bool)
4532 AddPromiseReactions(JSContext* cx, JS::HandleObject promise,
4533 JS::HandleObject onResolve, JS::HandleObject onReject);
4536 * Unforgeable version of the JS builtin Promise.all.
4538 * Takes an AutoObjectVector of Promise objects and returns a promise that's
4539 * resolved with an array of resolution values when all those promises ahve
4540 * been resolved, or rejected with the rejection value of the first rejected
4541 * promise.
4543 * Asserts if the array isn't dense or one of the entries isn't an unwrapped
4544 * instance of Promise or a subclass.
4546 extern JS_PUBLIC_API(JSObject*)
4547 GetWaitForAllPromise(JSContext* cx, const JS::AutoObjectVector& promises);
4549 } // namespace JS
4551 extern JS_PUBLIC_API(bool)
4552 JS_IsRunning(JSContext* cx);
4555 * Saving and restoring frame chains.
4557 * These two functions are used to set aside cx's call stack while that stack
4558 * is inactive. After a call to JS_SaveFrameChain, it looks as if there is no
4559 * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack
4560 * must be balanced and all nested calls to JS_SaveFrameChain must have had
4561 * matching JS_RestoreFrameChain calls.
4563 * JS_SaveFrameChain deals with cx not having any code running on it.
4565 extern JS_PUBLIC_API(bool)
4566 JS_SaveFrameChain(JSContext* cx);
4568 extern JS_PUBLIC_API(void)
4569 JS_RestoreFrameChain(JSContext* cx);
4571 namespace JS {
4574 * This class can be used to store a pointer to the youngest frame of a saved
4575 * stack in the specified JSContext. This reference will be picked up by any new
4576 * calls performed until the class is destroyed, with the specified asyncCause,
4577 * that must not be empty.
4579 * Any stack capture initiated during these new calls will go through the async
4580 * stack instead of the current stack.
4582 * Capturing the stack before a new call is performed will not be affected.
4584 * The provided chain of SavedFrame objects can live in any compartment,
4585 * although it will be copied to the compartment where the stack is captured.
4587 * See also `js/src/doc/SavedFrame/SavedFrame.md` for documentation on async
4588 * stack frames.
4590 class MOZ_STACK_CLASS JS_PUBLIC_API(AutoSetAsyncStackForNewCalls)
4592 JSContext* cx;
4593 RootedObject oldAsyncStack;
4594 const char* oldAsyncCause;
4595 bool oldAsyncCallIsExplicit;
4597 public:
4598 enum class AsyncCallKind {
4599 // The ordinary kind of call, where we may apply an async
4600 // parent if there is no ordinary parent.
4601 IMPLICIT,
4602 // An explicit async parent, e.g., callFunctionWithAsyncStack,
4603 // where we always want to override any ordinary parent.
4604 EXPLICIT
4607 // The stack parameter cannot be null by design, because it would be
4608 // ambiguous whether that would clear any scheduled async stack and make the
4609 // normal stack reappear in the new call, or just keep the async stack
4610 // already scheduled for the new call, if any.
4612 // asyncCause is owned by the caller and its lifetime must outlive the
4613 // lifetime of the AutoSetAsyncStackForNewCalls object. It is strongly
4614 // encouraged that asyncCause be a string constant or similar statically
4615 // allocated string.
4616 AutoSetAsyncStackForNewCalls(JSContext* cx, HandleObject stack,
4617 const char* asyncCause,
4618 AsyncCallKind kind = AsyncCallKind::IMPLICIT);
4619 ~AutoSetAsyncStackForNewCalls();
4622 } // namespace JS
4624 /************************************************************************/
4627 * Strings.
4629 * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
4630 * but on error (signified by null return), it leaves chars owned by the
4631 * caller. So the caller must free bytes in the error case, if it has no use
4632 * for them. In contrast, all the JS_New*StringCopy* functions do not take
4633 * ownership of the character memory passed to them -- they copy it.
4635 extern JS_PUBLIC_API(JSString*)
4636 JS_NewStringCopyN(JSContext* cx, const char* s, size_t n);
4638 extern JS_PUBLIC_API(JSString*)
4639 JS_NewStringCopyZ(JSContext* cx, const char* s);
4641 extern JS_PUBLIC_API(JSString*)
4642 JS_AtomizeAndPinJSString(JSContext* cx, JS::HandleString str);
4644 extern JS_PUBLIC_API(JSString*)
4645 JS_AtomizeStringN(JSContext* cx, const char* s, size_t length);
4647 extern JS_PUBLIC_API(JSString*)
4648 JS_AtomizeString(JSContext* cx, const char* s);
4650 extern JS_PUBLIC_API(JSString*)
4651 JS_AtomizeAndPinStringN(JSContext* cx, const char* s, size_t length);
4653 extern JS_PUBLIC_API(JSString*)
4654 JS_AtomizeAndPinString(JSContext* cx, const char* s);
4656 extern JS_PUBLIC_API(JSString*)
4657 JS_NewUCString(JSContext* cx, char16_t* chars, size_t length);
4659 extern JS_PUBLIC_API(JSString*)
4660 JS_NewUCStringCopyN(JSContext* cx, const char16_t* s, size_t n);
4662 extern JS_PUBLIC_API(JSString*)
4663 JS_NewUCStringCopyZ(JSContext* cx, const char16_t* s);
4665 extern JS_PUBLIC_API(JSString*)
4666 JS_AtomizeUCStringN(JSContext* cx, const char16_t* s, size_t length);
4668 extern JS_PUBLIC_API(JSString*)
4669 JS_AtomizeUCString(JSContext* cx, const char16_t* s);
4671 extern JS_PUBLIC_API(JSString*)
4672 JS_AtomizeAndPinUCStringN(JSContext* cx, const char16_t* s, size_t length);
4674 extern JS_PUBLIC_API(JSString*)
4675 JS_AtomizeAndPinUCString(JSContext* cx, const char16_t* s);
4677 extern JS_PUBLIC_API(bool)
4678 JS_CompareStrings(JSContext* cx, JSString* str1, JSString* str2, int32_t* result);
4680 extern JS_PUBLIC_API(bool)
4681 JS_StringEqualsAscii(JSContext* cx, JSString* str, const char* asciiBytes, bool* match);
4683 extern JS_PUBLIC_API(size_t)
4684 JS_PutEscapedString(JSContext* cx, char* buffer, size_t size, JSString* str, char quote);
4686 extern JS_PUBLIC_API(bool)
4687 JS_FileEscapedString(FILE* fp, JSString* str, char quote);
4690 * Extracting string characters and length.
4692 * While getting the length of a string is infallible, getting the chars can
4693 * fail. As indicated by the lack of a JSContext parameter, there are two
4694 * special cases where getting the chars is infallible:
4696 * The first case is for strings that have been atomized, e.g. directly by
4697 * JS_AtomizeAndPinString or implicitly because it is stored in a jsid.
4699 * The second case is "flat" strings that have been explicitly prepared in a
4700 * fallible context by JS_FlattenString. To catch errors, a separate opaque
4701 * JSFlatString type is returned by JS_FlattenString and expected by
4702 * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
4703 * distinction: the input and output of JS_FlattenString are the same actual
4704 * GC-thing. If a JSString is known to be flat, JS_ASSERT_STRING_IS_FLAT can be
4705 * used to make a debug-checked cast. Example:
4707 * // in a fallible context
4708 * JSFlatString* fstr = JS_FlattenString(cx, str);
4709 * if (!fstr)
4710 * return false;
4711 * MOZ_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
4713 * // in an infallible context, for the same 'str'
4714 * AutoCheckCannotGC nogc;
4715 * const char16_t* chars = JS_GetTwoByteFlatStringChars(nogc, fstr)
4716 * MOZ_ASSERT(chars);
4718 * Flat strings and interned strings are always null-terminated, so
4719 * JS_FlattenString can be used to get a null-terminated string.
4721 * Additionally, string characters are stored as either Latin1Char (8-bit)
4722 * or char16_t (16-bit). Clients can use JS_StringHasLatin1Chars and can then
4723 * call either the Latin1* or TwoByte* functions. Some functions like
4724 * JS_CopyStringChars and JS_GetStringCharAt accept both Latin1 and TwoByte
4725 * strings.
4728 extern JS_PUBLIC_API(size_t)
4729 JS_GetStringLength(JSString* str);
4731 extern JS_PUBLIC_API(bool)
4732 JS_StringIsFlat(JSString* str);
4734 /** Returns true iff the string's characters are stored as Latin1. */
4735 extern JS_PUBLIC_API(bool)
4736 JS_StringHasLatin1Chars(JSString* str);
4738 extern JS_PUBLIC_API(const JS::Latin1Char*)
4739 JS_GetLatin1StringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
4740 size_t* length);
4742 extern JS_PUBLIC_API(const char16_t*)
4743 JS_GetTwoByteStringCharsAndLength(JSContext* cx, const JS::AutoCheckCannotGC& nogc, JSString* str,
4744 size_t* length);
4746 extern JS_PUBLIC_API(bool)
4747 JS_GetStringCharAt(JSContext* cx, JSString* str, size_t index, char16_t* res);
4749 extern JS_PUBLIC_API(char16_t)
4750 JS_GetFlatStringCharAt(JSFlatString* str, size_t index);
4752 extern JS_PUBLIC_API(const char16_t*)
4753 JS_GetTwoByteExternalStringChars(JSString* str);
4755 extern JS_PUBLIC_API(bool)
4756 JS_CopyStringChars(JSContext* cx, mozilla::Range<char16_t> dest, JSString* str);
4758 extern JS_PUBLIC_API(JSFlatString*)
4759 JS_FlattenString(JSContext* cx, JSString* str);
4761 extern JS_PUBLIC_API(const JS::Latin1Char*)
4762 JS_GetLatin1FlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
4764 extern JS_PUBLIC_API(const char16_t*)
4765 JS_GetTwoByteFlatStringChars(const JS::AutoCheckCannotGC& nogc, JSFlatString* str);
4767 static MOZ_ALWAYS_INLINE JSFlatString*
4768 JSID_TO_FLAT_STRING(jsid id)
4770 MOZ_ASSERT(JSID_IS_STRING(id));
4771 return (JSFlatString*)(JSID_BITS(id));
4774 static MOZ_ALWAYS_INLINE JSFlatString*
4775 JS_ASSERT_STRING_IS_FLAT(JSString* str)
4777 MOZ_ASSERT(JS_StringIsFlat(str));
4778 return (JSFlatString*)str;
4781 static MOZ_ALWAYS_INLINE JSString*
4782 JS_FORGET_STRING_FLATNESS(JSFlatString* fstr)
4784 return (JSString*)fstr;
4788 * Additional APIs that avoid fallibility when given a flat string.
4791 extern JS_PUBLIC_API(bool)
4792 JS_FlatStringEqualsAscii(JSFlatString* str, const char* asciiBytes);
4794 extern JS_PUBLIC_API(size_t)
4795 JS_PutEscapedFlatString(char* buffer, size_t size, JSFlatString* str, char quote);
4798 * Create a dependent string, i.e., a string that owns no character storage,
4799 * but that refers to a slice of another string's chars. Dependent strings
4800 * are mutable by definition, so the thread safety comments above apply.
4802 extern JS_PUBLIC_API(JSString*)
4803 JS_NewDependentString(JSContext* cx, JS::HandleString str, size_t start,
4804 size_t length);
4807 * Concatenate two strings, possibly resulting in a rope.
4808 * See above for thread safety comments.
4810 extern JS_PUBLIC_API(JSString*)
4811 JS_ConcatStrings(JSContext* cx, JS::HandleString left, JS::HandleString right);
4814 * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
4815 * the call; on return, *dstlenp contains the number of characters actually
4816 * stored. To determine the necessary destination buffer size, make a sizing
4817 * call that passes nullptr for dst.
4819 * On errors, the functions report the error. In that case, *dstlenp contains
4820 * the number of characters or bytes transferred so far. If cx is nullptr, no
4821 * error is reported on failure, and the functions simply return false.
4823 * NB: This function does not store an additional zero byte or char16_t after the
4824 * transcoded string.
4826 JS_PUBLIC_API(bool)
4827 JS_DecodeBytes(JSContext* cx, const char* src, size_t srclen, char16_t* dst,
4828 size_t* dstlenp);
4831 * A variation on JS_EncodeCharacters where a null terminated string is
4832 * returned that you are expected to call JS_free on when done.
4834 JS_PUBLIC_API(char*)
4835 JS_EncodeString(JSContext* cx, JSString* str);
4838 * Same behavior as JS_EncodeString(), but encode into UTF-8 string
4840 JS_PUBLIC_API(char*)
4841 JS_EncodeStringToUTF8(JSContext* cx, JS::HandleString str);
4844 * Get number of bytes in the string encoding (without accounting for a
4845 * terminating zero bytes. The function returns (size_t) -1 if the string
4846 * can not be encoded into bytes and reports an error using cx accordingly.
4848 JS_PUBLIC_API(size_t)
4849 JS_GetStringEncodingLength(JSContext* cx, JSString* str);
4852 * Encode string into a buffer. The function does not stores an additional
4853 * zero byte. The function returns (size_t) -1 if the string can not be
4854 * encoded into bytes with no error reported. Otherwise it returns the number
4855 * of bytes that are necessary to encode the string. If that exceeds the
4856 * length parameter, the string will be cut and only length bytes will be
4857 * written into the buffer.
4859 JS_PUBLIC_API(size_t)
4860 JS_EncodeStringToBuffer(JSContext* cx, JSString* str, char* buffer, size_t length);
4862 class MOZ_RAII JSAutoByteString
4864 public:
4865 JSAutoByteString(JSContext* cx, JSString* str
4866 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
4867 : mBytes(JS_EncodeString(cx, str))
4869 MOZ_ASSERT(cx);
4870 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4873 explicit JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
4874 : mBytes(nullptr)
4876 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4879 ~JSAutoByteString() {
4880 JS_free(nullptr, mBytes);
4883 /* Take ownership of the given byte array. */
4884 void initBytes(char* bytes) {
4885 MOZ_ASSERT(!mBytes);
4886 mBytes = bytes;
4889 char* encodeLatin1(JSContext* cx, JSString* str) {
4890 MOZ_ASSERT(!mBytes);
4891 MOZ_ASSERT(cx);
4892 mBytes = JS_EncodeString(cx, str);
4893 return mBytes;
4896 char* encodeLatin1(js::ExclusiveContext* cx, JSString* str);
4898 char* encodeUtf8(JSContext* cx, JS::HandleString str) {
4899 MOZ_ASSERT(!mBytes);
4900 MOZ_ASSERT(cx);
4901 mBytes = JS_EncodeStringToUTF8(cx, str);
4902 return mBytes;
4905 void clear() {
4906 js_free(mBytes);
4907 mBytes = nullptr;
4910 char* ptr() const {
4911 return mBytes;
4914 bool operator!() const {
4915 return !mBytes;
4918 size_t length() const {
4919 if (!mBytes)
4920 return 0;
4921 return strlen(mBytes);
4924 private:
4925 char* mBytes;
4926 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
4928 /* Copy and assignment are not supported. */
4929 JSAutoByteString(const JSAutoByteString& another);
4930 JSAutoByteString& operator=(const JSAutoByteString& another);
4933 namespace JS {
4935 extern JS_PUBLIC_API(JSAddonId*)
4936 NewAddonId(JSContext* cx, JS::HandleString str);
4938 extern JS_PUBLIC_API(JSString*)
4939 StringOfAddonId(JSAddonId* id);
4941 extern JS_PUBLIC_API(JSAddonId*)
4942 AddonIdOfObject(JSObject* obj);
4944 } // namespace JS
4946 /************************************************************************/
4948 * Symbols
4951 namespace JS {
4954 * Create a new Symbol with the given description. This function never returns
4955 * a Symbol that is in the Runtime-wide symbol registry.
4957 * If description is null, the new Symbol's [[Description]] attribute is
4958 * undefined.
4960 JS_PUBLIC_API(Symbol*)
4961 NewSymbol(JSContext* cx, HandleString description);
4964 * Symbol.for as specified in ES6.
4966 * Get a Symbol with the description 'key' from the Runtime-wide symbol registry.
4967 * If there is not already a Symbol with that description in the registry, a new
4968 * Symbol is created and registered. 'key' must not be null.
4970 JS_PUBLIC_API(Symbol*)
4971 GetSymbolFor(JSContext* cx, HandleString key);
4974 * Get the [[Description]] attribute of the given symbol.
4976 * This function is infallible. If it returns null, that means the symbol's
4977 * [[Description]] is undefined.
4979 JS_PUBLIC_API(JSString*)
4980 GetSymbolDescription(HandleSymbol symbol);
4982 /* Well-known symbols. */
4983 #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(macro) \
4984 macro(isConcatSpreadable) \
4985 macro(iterator) \
4986 macro(match) \
4987 macro(replace) \
4988 macro(search) \
4989 macro(species) \
4990 macro(split) \
4991 macro(toPrimitive) \
4992 macro(unscopables)
4994 enum class SymbolCode : uint32_t {
4995 // There is one SymbolCode for each well-known symbol.
4996 #define JS_DEFINE_SYMBOL_ENUM(name) name,
4997 JS_FOR_EACH_WELL_KNOWN_SYMBOL(JS_DEFINE_SYMBOL_ENUM) // SymbolCode::iterator, etc.
4998 #undef JS_DEFINE_SYMBOL_ENUM
4999 Limit,
5000 InSymbolRegistry = 0xfffffffe, // created by Symbol.for() or JS::GetSymbolFor()
5001 UniqueSymbol = 0xffffffff // created by Symbol() or JS::NewSymbol()
5004 /* For use in loops that iterate over the well-known symbols. */
5005 const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
5008 * Return the SymbolCode telling what sort of symbol `symbol` is.
5010 * A symbol's SymbolCode never changes once it is created.
5012 JS_PUBLIC_API(SymbolCode)
5013 GetSymbolCode(Handle<Symbol*> symbol);
5016 * Get one of the well-known symbols defined by ES6. A single set of well-known
5017 * symbols is shared by all compartments in a JSRuntime.
5019 * `which` must be in the range [0, WellKnownSymbolLimit).
5021 JS_PUBLIC_API(Symbol*)
5022 GetWellKnownSymbol(JSContext* cx, SymbolCode which);
5025 * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
5026 * is actually a symbol code and not a string. See JS_SYM_FN.
5028 inline bool
5029 PropertySpecNameIsSymbol(const char* name)
5031 uintptr_t u = reinterpret_cast<uintptr_t>(name);
5032 return u != 0 && u - 1 < WellKnownSymbolLimit;
5035 JS_PUBLIC_API(bool)
5036 PropertySpecNameEqualsId(const char* name, HandleId id);
5039 * Create a jsid that does not need to be marked for GC.
5041 * 'name' is a JSPropertySpec::name or JSFunctionSpec::name value. The
5042 * resulting jsid, on success, is either an interned string or a well-known
5043 * symbol; either way it is immune to GC so there is no need to visit *idp
5044 * during GC marking.
5046 JS_PUBLIC_API(bool)
5047 PropertySpecNameToPermanentId(JSContext* cx, const char* name, jsid* idp);
5049 } /* namespace JS */
5051 /************************************************************************/
5053 * JSON functions
5055 typedef bool (* JSONWriteCallback)(const char16_t* buf, uint32_t len, void* data);
5058 * JSON.stringify as specified by ES5.
5060 JS_PUBLIC_API(bool)
5061 JS_Stringify(JSContext* cx, JS::MutableHandleValue value, JS::HandleObject replacer,
5062 JS::HandleValue space, JSONWriteCallback callback, void* data);
5064 namespace JS {
5067 * An API akin to JS_Stringify but with the goal of not having observable
5068 * side-effects when the stringification is performed. This means it does not
5069 * allow a replacer or a custom space, and has the following constraints on its
5070 * input:
5072 * 1) The input must be a plain object or array, not an abitrary value.
5073 * 2) Every value in the graph reached by the algorithm starting with this
5074 * object must be one of the following: null, undefined, a string (NOT a
5075 * string object!), a boolean, a finite number (i.e. no NaN or Infinity or
5076 * -Infinity), a plain object with no accessor properties, or an Array with
5077 * no holes.
5079 * The actual behavior differs from JS_Stringify only in asserting the above and
5080 * NOT attempting to get the "toJSON" property from things, since that could
5081 * clearly have side-effects.
5083 JS_PUBLIC_API(bool)
5084 ToJSONMaybeSafely(JSContext* cx, JS::HandleObject input,
5085 JSONWriteCallback callback, void* data);
5087 } /* namespace JS */
5090 * JSON.parse as specified by ES5.
5092 JS_PUBLIC_API(bool)
5093 JS_ParseJSON(JSContext* cx, const char16_t* chars, uint32_t len, JS::MutableHandleValue vp);
5095 JS_PUBLIC_API(bool)
5096 JS_ParseJSON(JSContext* cx, JS::HandleString str, JS::MutableHandleValue vp);
5098 JS_PUBLIC_API(bool)
5099 JS_ParseJSONWithReviver(JSContext* cx, const char16_t* chars, uint32_t len, JS::HandleValue reviver,
5100 JS::MutableHandleValue vp);
5102 JS_PUBLIC_API(bool)
5103 JS_ParseJSONWithReviver(JSContext* cx, JS::HandleString str, JS::HandleValue reviver,
5104 JS::MutableHandleValue vp);
5106 /************************************************************************/
5109 * The default locale for the ECMAScript Internationalization API
5110 * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
5111 * Note that the Internationalization API encourages clients to
5112 * specify their own locales.
5113 * The locale string remains owned by the caller.
5115 extern JS_PUBLIC_API(bool)
5116 JS_SetDefaultLocale(JSRuntime* rt, const char* locale);
5119 * Reset the default locale to OS defaults.
5121 extern JS_PUBLIC_API(void)
5122 JS_ResetDefaultLocale(JSRuntime* rt);
5125 * Locale specific string conversion and error message callbacks.
5127 struct JSLocaleCallbacks {
5128 JSLocaleToUpperCase localeToUpperCase;
5129 JSLocaleToLowerCase localeToLowerCase;
5130 JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API
5131 JSLocaleToUnicode localeToUnicode;
5135 * Establish locale callbacks. The pointer must persist as long as the
5136 * JSRuntime. Passing nullptr restores the default behaviour.
5138 extern JS_PUBLIC_API(void)
5139 JS_SetLocaleCallbacks(JSRuntime* rt, const JSLocaleCallbacks* callbacks);
5142 * Return the address of the current locale callbacks struct, which may
5143 * be nullptr.
5145 extern JS_PUBLIC_API(const JSLocaleCallbacks*)
5146 JS_GetLocaleCallbacks(JSRuntime* rt);
5148 /************************************************************************/
5151 * Error reporting.
5154 namespace JS {
5155 const uint16_t MaxNumErrorArguments = 10;
5159 * Report an exception represented by the sprintf-like conversion of format
5160 * and its arguments. This exception message string is passed to a pre-set
5161 * JSErrorReporter function (set by JS_SetErrorReporter).
5163 extern JS_PUBLIC_API(void)
5164 JS_ReportError(JSContext* cx, const char* format, ...);
5167 * Use an errorNumber to retrieve the format string, args are char*
5169 extern JS_PUBLIC_API(void)
5170 JS_ReportErrorNumber(JSContext* cx, JSErrorCallback errorCallback,
5171 void* userRef, const unsigned errorNumber, ...);
5173 #ifdef va_start
5174 extern JS_PUBLIC_API(void)
5175 JS_ReportErrorNumberVA(JSContext* cx, JSErrorCallback errorCallback,
5176 void* userRef, const unsigned errorNumber, va_list ap);
5177 #endif
5180 * Use an errorNumber to retrieve the format string, args are char16_t*
5182 extern JS_PUBLIC_API(void)
5183 JS_ReportErrorNumberUC(JSContext* cx, JSErrorCallback errorCallback,
5184 void* userRef, const unsigned errorNumber, ...);
5186 extern JS_PUBLIC_API(void)
5187 JS_ReportErrorNumberUCArray(JSContext* cx, JSErrorCallback errorCallback,
5188 void* userRef, const unsigned errorNumber,
5189 const char16_t** args);
5192 * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
5193 * Return true if there was no error trying to issue the warning, and if the
5194 * warning was not converted into an error due to the JSOPTION_WERROR option
5195 * being set, false otherwise.
5197 extern JS_PUBLIC_API(bool)
5198 JS_ReportWarning(JSContext* cx, const char* format, ...);
5200 extern JS_PUBLIC_API(bool)
5201 JS_ReportErrorFlagsAndNumber(JSContext* cx, unsigned flags,
5202 JSErrorCallback errorCallback, void* userRef,
5203 const unsigned errorNumber, ...);
5205 extern JS_PUBLIC_API(bool)
5206 JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags,
5207 JSErrorCallback errorCallback, void* userRef,
5208 const unsigned errorNumber, ...);
5211 * Complain when out of memory.
5213 extern JS_PUBLIC_API(void)
5214 JS_ReportOutOfMemory(JSContext* cx);
5217 * Complain when an allocation size overflows the maximum supported limit.
5219 extern JS_PUBLIC_API(void)
5220 JS_ReportAllocationOverflow(JSContext* cx);
5222 class JSErrorReport
5224 // Offending source line without final '\n'.
5225 const char16_t* linebuf_;
5227 // Number of chars in linebuf_. Does not include trailing '\0'.
5228 size_t linebufLength_;
5230 // The 0-based offset of error token in linebuf_.
5231 size_t tokenOffset_;
5233 public:
5234 JSErrorReport()
5235 : linebuf_(nullptr), linebufLength_(0), tokenOffset_(0),
5236 filename(nullptr), lineno(0), column(0), isMuted(false),
5237 flags(0), errorNumber(0), ucmessage(nullptr),
5238 messageArgs(nullptr), exnType(0)
5241 const char* filename; /* source file name, URL, etc., or null */
5242 unsigned lineno; /* source line number */
5243 unsigned column; /* zero-based column index in line */
5244 bool isMuted; /* See the comment in ReadOnlyCompileOptions. */
5245 unsigned flags; /* error/warning, etc. */
5246 unsigned errorNumber; /* the error number, e.g. see js.msg */
5247 const char16_t* ucmessage; /* the (default) error message */
5248 const char16_t** messageArgs; /* arguments for the error message */
5249 int16_t exnType; /* One of the JSExnType constants */
5251 const char16_t* linebuf() const {
5252 return linebuf_;
5254 size_t linebufLength() const {
5255 return linebufLength_;
5257 size_t tokenOffset() const {
5258 return tokenOffset_;
5260 void initLinebuf(const char16_t* linebuf, size_t linebufLength, size_t tokenOffset);
5264 * JSErrorReport flag values. These may be freely composed.
5266 #define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */
5267 #define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
5268 #define JSREPORT_EXCEPTION 0x2 /* exception was thrown */
5269 #define JSREPORT_STRICT 0x4 /* error or warning due to strict option */
5272 * This condition is an error in strict mode code, a warning if
5273 * JS_HAS_STRICT_OPTION(cx), and otherwise should not be reported at
5274 * all. We check the strictness of the context's top frame's script;
5275 * where that isn't appropriate, the caller should do the right checks
5276 * itself instead of using this flag.
5278 #define JSREPORT_STRICT_MODE_ERROR 0x8
5281 * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
5282 * has been thrown for this runtime error, and the host should ignore it.
5283 * Exception-aware hosts should also check for JS_IsExceptionPending if
5284 * JS_ExecuteScript returns failure, and signal or propagate the exception, as
5285 * appropriate.
5287 #define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0)
5288 #define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0)
5289 #define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0)
5290 #define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) & \
5291 JSREPORT_STRICT_MODE_ERROR) != 0)
5292 extern JS_PUBLIC_API(JSErrorReporter)
5293 JS_GetErrorReporter(JSRuntime* rt);
5295 extern JS_PUBLIC_API(JSErrorReporter)
5296 JS_SetErrorReporter(JSRuntime* rt, JSErrorReporter er);
5298 namespace JS {
5300 extern JS_PUBLIC_API(bool)
5301 CreateError(JSContext* cx, JSExnType type, HandleObject stack,
5302 HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
5303 JSErrorReport* report, HandleString message, MutableHandleValue rval);
5305 /************************************************************************/
5308 * Weak Maps.
5311 extern JS_PUBLIC_API(JSObject*)
5312 NewWeakMapObject(JSContext* cx);
5314 extern JS_PUBLIC_API(bool)
5315 IsWeakMapObject(JSObject* obj);
5317 extern JS_PUBLIC_API(bool)
5318 GetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
5319 JS::MutableHandleValue val);
5321 extern JS_PUBLIC_API(bool)
5322 SetWeakMapEntry(JSContext* cx, JS::HandleObject mapObj, JS::HandleObject key,
5323 JS::HandleValue val);
5326 * Map
5328 extern JS_PUBLIC_API(JSObject*)
5329 NewMapObject(JSContext* cx);
5331 extern JS_PUBLIC_API(uint32_t)
5332 MapSize(JSContext* cx, HandleObject obj);
5334 extern JS_PUBLIC_API(bool)
5335 MapGet(JSContext* cx, HandleObject obj,
5336 HandleValue key, MutableHandleValue rval);
5338 extern JS_PUBLIC_API(bool)
5339 MapHas(JSContext* cx, HandleObject obj, HandleValue key, bool* rval);
5341 extern JS_PUBLIC_API(bool)
5342 MapSet(JSContext* cx, HandleObject obj, HandleValue key, HandleValue val);
5344 extern JS_PUBLIC_API(bool)
5345 MapDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
5347 extern JS_PUBLIC_API(bool)
5348 MapClear(JSContext* cx, HandleObject obj);
5350 extern JS_PUBLIC_API(bool)
5351 MapKeys(JSContext* cx, HandleObject obj, MutableHandleValue rval);
5353 extern JS_PUBLIC_API(bool)
5354 MapValues(JSContext* cx, HandleObject obj, MutableHandleValue rval);
5356 extern JS_PUBLIC_API(bool)
5357 MapEntries(JSContext* cx, HandleObject obj, MutableHandleValue rval);
5359 extern JS_PUBLIC_API(bool)
5360 MapForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
5363 * Set
5365 extern JS_PUBLIC_API(JSObject *)
5366 NewSetObject(JSContext *cx);
5368 extern JS_PUBLIC_API(uint32_t)
5369 SetSize(JSContext *cx, HandleObject obj);
5371 extern JS_PUBLIC_API(bool)
5372 SetHas(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
5374 extern JS_PUBLIC_API(bool)
5375 SetDelete(JSContext *cx, HandleObject obj, HandleValue key, bool *rval);
5377 extern JS_PUBLIC_API(bool)
5378 SetAdd(JSContext *cx, HandleObject obj, HandleValue key);
5380 extern JS_PUBLIC_API(bool)
5381 SetClear(JSContext *cx, HandleObject obj);
5383 extern JS_PUBLIC_API(bool)
5384 SetKeys(JSContext *cx, HandleObject obj, MutableHandleValue rval);
5386 extern JS_PUBLIC_API(bool)
5387 SetValues(JSContext *cx, HandleObject obj, MutableHandleValue rval);
5389 extern JS_PUBLIC_API(bool)
5390 SetEntries(JSContext *cx, HandleObject obj, MutableHandleValue rval);
5392 extern JS_PUBLIC_API(bool)
5393 SetForEach(JSContext *cx, HandleObject obj, HandleValue callbackFn, HandleValue thisVal);
5395 } /* namespace JS */
5398 * Dates.
5401 extern JS_PUBLIC_API(JSObject*)
5402 JS_NewDateObject(JSContext* cx, int year, int mon, int mday, int hour, int min, int sec);
5405 * Returns true and sets |*isDate| indicating whether |obj| is a Date object or
5406 * a wrapper around one, otherwise returns false on failure.
5408 * This method returns true with |*isDate == false| when passed a proxy whose
5409 * target is a Date, or when passed a revoked proxy.
5411 extern JS_PUBLIC_API(bool)
5412 JS_ObjectIsDate(JSContext* cx, JS::HandleObject obj, bool* isDate);
5414 /************************************************************************/
5417 * Regular Expressions.
5419 #define JSREG_FOLD 0x01u /* fold uppercase to lowercase */
5420 #define JSREG_GLOB 0x02u /* global exec, creates array of matches */
5421 #define JSREG_MULTILINE 0x04u /* treat ^ and $ as begin and end of line */
5422 #define JSREG_STICKY 0x08u /* only match starting at lastIndex */
5423 #define JSREG_UNICODE 0x10u /* unicode */
5425 extern JS_PUBLIC_API(JSObject*)
5426 JS_NewRegExpObject(JSContext* cx, const char* bytes, size_t length, unsigned flags);
5428 extern JS_PUBLIC_API(JSObject*)
5429 JS_NewUCRegExpObject(JSContext* cx, const char16_t* chars, size_t length, unsigned flags);
5431 extern JS_PUBLIC_API(bool)
5432 JS_SetRegExpInput(JSContext* cx, JS::HandleObject obj, JS::HandleString input);
5434 extern JS_PUBLIC_API(bool)
5435 JS_ClearRegExpStatics(JSContext* cx, JS::HandleObject obj);
5437 extern JS_PUBLIC_API(bool)
5438 JS_ExecuteRegExp(JSContext* cx, JS::HandleObject obj, JS::HandleObject reobj,
5439 char16_t* chars, size_t length, size_t* indexp, bool test,
5440 JS::MutableHandleValue rval);
5442 /* RegExp interface for clients without a global object. */
5444 extern JS_PUBLIC_API(bool)
5445 JS_ExecuteRegExpNoStatics(JSContext* cx, JS::HandleObject reobj, char16_t* chars, size_t length,
5446 size_t* indexp, bool test, JS::MutableHandleValue rval);
5449 * Returns true and sets |*isRegExp| indicating whether |obj| is a RegExp
5450 * object or a wrapper around one, otherwise returns false on failure.
5452 * This method returns true with |*isRegExp == false| when passed a proxy whose
5453 * target is a RegExp, or when passed a revoked proxy.
5455 extern JS_PUBLIC_API(bool)
5456 JS_ObjectIsRegExp(JSContext* cx, JS::HandleObject obj, bool* isRegExp);
5458 extern JS_PUBLIC_API(unsigned)
5459 JS_GetRegExpFlags(JSContext* cx, JS::HandleObject obj);
5461 extern JS_PUBLIC_API(JSString*)
5462 JS_GetRegExpSource(JSContext* cx, JS::HandleObject obj);
5464 /************************************************************************/
5466 extern JS_PUBLIC_API(bool)
5467 JS_IsExceptionPending(JSContext* cx);
5469 extern JS_PUBLIC_API(bool)
5470 JS_GetPendingException(JSContext* cx, JS::MutableHandleValue vp);
5472 extern JS_PUBLIC_API(void)
5473 JS_SetPendingException(JSContext* cx, JS::HandleValue v);
5475 extern JS_PUBLIC_API(void)
5476 JS_ClearPendingException(JSContext* cx);
5478 extern JS_PUBLIC_API(bool)
5479 JS_ReportPendingException(JSContext* cx);
5481 namespace JS {
5484 * Save and later restore the current exception state of a given JSContext.
5485 * This is useful for implementing behavior in C++ that's like try/catch
5486 * or try/finally in JS.
5488 * Typical usage:
5490 * bool ok = JS::Evaluate(cx, ...);
5491 * AutoSaveExceptionState savedExc(cx);
5492 * ... cleanup that might re-enter JS ...
5493 * return ok;
5495 class JS_PUBLIC_API(AutoSaveExceptionState)
5497 private:
5498 JSContext* context;
5499 bool wasPropagatingForcedReturn;
5500 bool wasOverRecursed;
5501 bool wasThrowing;
5502 RootedValue exceptionValue;
5504 public:
5506 * Take a snapshot of cx's current exception state. Then clear any current
5507 * pending exception in cx.
5509 explicit AutoSaveExceptionState(JSContext* cx);
5512 * If neither drop() nor restore() was called, restore the exception
5513 * state only if no exception is currently pending on cx.
5515 ~AutoSaveExceptionState();
5518 * Discard any stored exception state.
5519 * If this is called, the destructor is a no-op.
5521 void drop() {
5522 wasPropagatingForcedReturn = false;
5523 wasOverRecursed = false;
5524 wasThrowing = false;
5525 exceptionValue.setUndefined();
5529 * Replace cx's exception state with the stored exception state. Then
5530 * discard the stored exception state. If this is called, the
5531 * destructor is a no-op.
5533 void restore();
5536 } /* namespace JS */
5538 /* Deprecated API. Use AutoSaveExceptionState instead. */
5539 extern JS_PUBLIC_API(JSExceptionState*)
5540 JS_SaveExceptionState(JSContext* cx);
5542 extern JS_PUBLIC_API(void)
5543 JS_RestoreExceptionState(JSContext* cx, JSExceptionState* state);
5545 extern JS_PUBLIC_API(void)
5546 JS_DropExceptionState(JSContext* cx, JSExceptionState* state);
5549 * If the given object is an exception object, the exception will have (or be
5550 * able to lazily create) an error report struct, and this function will return
5551 * the address of that struct. Otherwise, it returns nullptr. The lifetime
5552 * of the error report struct that might be returned is the same as the
5553 * lifetime of the exception object.
5555 extern JS_PUBLIC_API(JSErrorReport*)
5556 JS_ErrorFromException(JSContext* cx, JS::HandleObject obj);
5559 * If the given object is an exception object (or an unwrappable
5560 * cross-compartment wrapper for one), return the stack for that exception, if
5561 * any. Will return null if the given object is not an exception object
5562 * (including if it's null or a security wrapper that can't be unwrapped) or if
5563 * the exception has no stack.
5565 extern JS_PUBLIC_API(JSObject*)
5566 ExceptionStackOrNull(JS::HandleObject obj);
5569 * Throws a StopIteration exception on cx.
5571 extern JS_PUBLIC_API(bool)
5572 JS_ThrowStopIteration(JSContext* cx);
5574 extern JS_PUBLIC_API(bool)
5575 JS_IsStopIteration(JS::Value v);
5577 extern JS_PUBLIC_API(intptr_t)
5578 JS_GetCurrentThread();
5581 * A JS runtime always has an "owner thread". The owner thread is set when the
5582 * runtime is created (to the current thread) and practically all entry points
5583 * into the JS engine check that a runtime (or anything contained in the
5584 * runtime: context, compartment, object, etc) is only touched by its owner
5585 * thread. Embeddings may check this invariant outside the JS engine by calling
5586 * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
5587 * non-debug builds).
5590 extern JS_PUBLIC_API(void)
5591 JS_AbortIfWrongThread(JSRuntime* rt);
5593 /************************************************************************/
5596 * A constructor can request that the JS engine create a default new 'this'
5597 * object of the given class, using the callee to determine parentage and
5598 * [[Prototype]].
5600 extern JS_PUBLIC_API(JSObject*)
5601 JS_NewObjectForConstructor(JSContext* cx, const JSClass* clasp, const JS::CallArgs& args);
5603 /************************************************************************/
5605 #ifdef JS_GC_ZEAL
5606 #define JS_DEFAULT_ZEAL_FREQ 100
5608 extern JS_PUBLIC_API(void)
5609 JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled);
5611 extern JS_PUBLIC_API(void)
5612 JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency);
5614 extern JS_PUBLIC_API(void)
5615 JS_ScheduleGC(JSContext* cx, uint32_t count);
5616 #endif
5618 extern JS_PUBLIC_API(void)
5619 JS_SetParallelParsingEnabled(JSRuntime* rt, bool enabled);
5621 extern JS_PUBLIC_API(void)
5622 JS_SetOffthreadIonCompilationEnabled(JSRuntime* rt, bool enabled);
5624 #define JIT_COMPILER_OPTIONS(Register) \
5625 Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
5626 Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
5627 Register(ION_GVN_ENABLE, "ion.gvn.enable") \
5628 Register(ION_FORCE_IC, "ion.forceinlineCaches") \
5629 Register(ION_ENABLE, "ion.enable") \
5630 Register(BASELINE_ENABLE, "baseline.enable") \
5631 Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
5632 Register(SIGNALS_ENABLE, "signals.enable") \
5633 Register(JUMP_THRESHOLD, "jump-threshold") \
5634 Register(WASM_TEST_MODE, "wasm.test-mode")
5636 typedef enum JSJitCompilerOption {
5637 #define JIT_COMPILER_DECLARE(key, str) \
5638 JSJITCOMPILER_ ## key,
5640 JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
5641 #undef JIT_COMPILER_DECLARE
5643 JSJITCOMPILER_NOT_AN_OPTION
5644 } JSJitCompilerOption;
5646 extern JS_PUBLIC_API(void)
5647 JS_SetGlobalJitCompilerOption(JSRuntime* rt, JSJitCompilerOption opt, uint32_t value);
5648 extern JS_PUBLIC_API(int)
5649 JS_GetGlobalJitCompilerOption(JSRuntime* rt, JSJitCompilerOption opt);
5652 * Convert a uint32_t index into a jsid.
5654 extern JS_PUBLIC_API(bool)
5655 JS_IndexToId(JSContext* cx, uint32_t index, JS::MutableHandleId);
5658 * Convert chars into a jsid.
5660 * |chars| may not be an index.
5662 extern JS_PUBLIC_API(bool)
5663 JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
5666 * Test if the given string is a valid ECMAScript identifier
5668 extern JS_PUBLIC_API(bool)
5669 JS_IsIdentifier(JSContext* cx, JS::HandleString str, bool* isIdentifier);
5672 * Test whether the given chars + length are a valid ECMAScript identifier.
5673 * This version is infallible, so just returns whether the chars are an
5674 * identifier.
5676 extern JS_PUBLIC_API(bool)
5677 JS_IsIdentifier(const char16_t* chars, size_t length);
5679 namespace js {
5680 class ScriptSource;
5681 } // namespace js
5683 namespace JS {
5685 class MOZ_RAII JS_PUBLIC_API(AutoFilename)
5687 private:
5688 js::ScriptSource* ss_;
5689 mozilla::Variant<const char*, UniqueChars> filename_;
5691 AutoFilename(const AutoFilename&) = delete;
5692 AutoFilename& operator=(const AutoFilename&) = delete;
5694 public:
5695 AutoFilename()
5696 : ss_(nullptr),
5697 filename_(mozilla::AsVariant<const char*>(nullptr))
5700 ~AutoFilename() {
5701 reset();
5704 void reset();
5706 void setOwned(UniqueChars&& filename);
5707 void setUnowned(const char* filename);
5708 void setScriptSource(js::ScriptSource* ss);
5710 const char* get() const;
5714 * Return the current filename, line number and column number of the most
5715 * currently running frame. Returns true if a scripted frame was found, false
5716 * otherwise.
5718 * If a the embedding has hidden the scripted caller for the topmost activation
5719 * record, this will also return false.
5721 extern JS_PUBLIC_API(bool)
5722 DescribeScriptedCaller(JSContext* cx, AutoFilename* filename = nullptr,
5723 unsigned* lineno = nullptr, unsigned* column = nullptr);
5725 extern JS_PUBLIC_API(JSObject*)
5726 GetScriptedCallerGlobal(JSContext* cx);
5729 * Informs the JS engine that the scripted caller should be hidden. This can be
5730 * used by the embedding to maintain an override of the scripted caller in its
5731 * calculations, by hiding the scripted caller in the JS engine and pushing data
5732 * onto a separate stack, which it inspects when DescribeScriptedCaller returns
5733 * null.
5735 * We maintain a counter on each activation record. Add() increments the counter
5736 * of the topmost activation, and Remove() decrements it. The count may never
5737 * drop below zero, and must always be exactly zero when the activation is
5738 * popped from the stack.
5740 extern JS_PUBLIC_API(void)
5741 HideScriptedCaller(JSContext* cx);
5743 extern JS_PUBLIC_API(void)
5744 UnhideScriptedCaller(JSContext* cx);
5746 class MOZ_RAII AutoHideScriptedCaller
5748 public:
5749 explicit AutoHideScriptedCaller(JSContext* cx
5750 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
5751 : mContext(cx)
5753 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
5754 HideScriptedCaller(mContext);
5756 ~AutoHideScriptedCaller() {
5757 UnhideScriptedCaller(mContext);
5760 protected:
5761 JSContext* mContext;
5762 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
5765 } /* namespace JS */
5768 * Encode/Decode interpreted scripts and functions to/from memory.
5771 extern JS_PUBLIC_API(void*)
5772 JS_EncodeScript(JSContext* cx, JS::HandleScript script, uint32_t* lengthp);
5774 extern JS_PUBLIC_API(void*)
5775 JS_EncodeInterpretedFunction(JSContext* cx, JS::HandleObject funobj, uint32_t* lengthp);
5777 extern JS_PUBLIC_API(JSScript*)
5778 JS_DecodeScript(JSContext* cx, const void* data, uint32_t length);
5780 extern JS_PUBLIC_API(JSObject*)
5781 JS_DecodeInterpretedFunction(JSContext* cx, const void* data, uint32_t length);
5783 namespace JS {
5786 * This callback represents a request by the JS engine to open for reading the
5787 * existing cache entry for the given global and char range that may contain a
5788 * module. If a cache entry exists, the callback shall return 'true' and return
5789 * the size, base address and an opaque file handle as outparams. If the
5790 * callback returns 'true', the JS engine guarantees a call to
5791 * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
5792 * handle.
5794 typedef bool
5795 (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const char16_t* begin, const char16_t* limit,
5796 size_t* size, const uint8_t** memory, intptr_t* handle);
5797 typedef void
5798 (* CloseAsmJSCacheEntryForReadOp)(size_t size, const uint8_t* memory, intptr_t handle);
5800 /** The list of reasons why an asm.js module may not be stored in the cache. */
5801 enum AsmJSCacheResult
5803 AsmJSCache_MIN,
5804 AsmJSCache_Success = AsmJSCache_MIN,
5805 AsmJSCache_ModuleTooSmall,
5806 AsmJSCache_SynchronousScript,
5807 AsmJSCache_QuotaExceeded,
5808 AsmJSCache_StorageInitFailure,
5809 AsmJSCache_Disabled_Internal,
5810 AsmJSCache_Disabled_ShellFlags,
5811 AsmJSCache_Disabled_JitInspector,
5812 AsmJSCache_InternalError,
5813 AsmJSCache_LIMIT
5817 * This callback represents a request by the JS engine to open for writing a
5818 * cache entry of the given size for the given global and char range containing
5819 * the just-compiled module. If cache entry space is available, the callback
5820 * shall return 'true' and return the base address and an opaque file handle as
5821 * outparams. If the callback returns 'true', the JS engine guarantees a call
5822 * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
5823 * handle.
5825 * If 'installed' is true, then the cache entry is associated with a permanently
5826 * installed JS file (e.g., in a packaged webapp). This information allows the
5827 * embedding to store the cache entry in a installed location associated with
5828 * the principal of 'global' where it will not be evicted until the associated
5829 * installed JS file is removed.
5831 typedef AsmJSCacheResult
5832 (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
5833 const char16_t* begin, const char16_t* end,
5834 size_t size, uint8_t** memory, intptr_t* handle);
5835 typedef void
5836 (* CloseAsmJSCacheEntryForWriteOp)(size_t size, uint8_t* memory, intptr_t handle);
5838 typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
5841 * Return the buildId (represented as a sequence of characters) associated with
5842 * the currently-executing build. If the JS engine is embedded such that a
5843 * single cache entry can be observed by different compiled versions of the JS
5844 * engine, it is critical that the buildId shall change for each new build of
5845 * the JS engine.
5847 typedef bool
5848 (* BuildIdOp)(BuildIdCharVector* buildId);
5850 struct AsmJSCacheOps
5852 OpenAsmJSCacheEntryForReadOp openEntryForRead;
5853 CloseAsmJSCacheEntryForReadOp closeEntryForRead;
5854 OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
5855 CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
5858 extern JS_PUBLIC_API(void)
5859 SetAsmJSCacheOps(JSRuntime* rt, const AsmJSCacheOps* callbacks);
5861 extern JS_PUBLIC_API(void)
5862 SetBuildIdOp(JSRuntime* rt, BuildIdOp buildIdOp);
5865 * Convenience class for imitating a JS level for-of loop. Typical usage:
5867 * ForOfIterator it(cx);
5868 * if (!it.init(iterable))
5869 * return false;
5870 * RootedValue val(cx);
5871 * while (true) {
5872 * bool done;
5873 * if (!it.next(&val, &done))
5874 * return false;
5875 * if (done)
5876 * break;
5877 * if (!DoStuff(cx, val))
5878 * return false;
5881 class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
5882 protected:
5883 JSContext* cx_;
5885 * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
5886 * to optimize iteration across arrays.
5888 * Case 1: Regular Iteration
5889 * iterator - pointer to the iterator object.
5890 * index - fixed to NOT_ARRAY (== UINT32_MAX)
5892 * Case 2: Optimized Array Iteration
5893 * iterator - pointer to the array object.
5894 * index - current position in array.
5896 * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
5898 JS::RootedObject iterator;
5899 uint32_t index;
5901 static const uint32_t NOT_ARRAY = UINT32_MAX;
5903 ForOfIterator(const ForOfIterator&) = delete;
5904 ForOfIterator& operator=(const ForOfIterator&) = delete;
5906 public:
5907 explicit ForOfIterator(JSContext* cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
5909 enum NonIterableBehavior {
5910 ThrowOnNonIterable,
5911 AllowNonIterable
5915 * Initialize the iterator. If AllowNonIterable is passed then if getting
5916 * the @@iterator property from iterable returns undefined init() will just
5917 * return true instead of throwing. Callers must then check
5918 * valueIsIterable() before continuing with the iteration.
5920 bool init(JS::HandleValue iterable,
5921 NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
5924 * Get the next value from the iterator. If false *done is true
5925 * after this call, do not examine val.
5927 bool next(JS::MutableHandleValue val, bool* done);
5930 * If initialized with throwOnNonCallable = false, check whether
5931 * the value is iterable.
5933 bool valueIsIterable() const {
5934 return iterator;
5937 private:
5938 inline bool nextFromOptimizedArray(MutableHandleValue val, bool* done);
5939 bool materializeArrayIterator();
5944 * If a large allocation fails when calling pod_{calloc,realloc}CanGC, the JS
5945 * engine may call the large-allocation- failure callback, if set, to allow the
5946 * embedding to flush caches, possibly perform shrinking GCs, etc. to make some
5947 * room. The allocation will then be retried (and may still fail.)
5950 typedef void
5951 (* LargeAllocationFailureCallback)(void* data);
5953 extern JS_PUBLIC_API(void)
5954 SetLargeAllocationFailureCallback(JSRuntime* rt, LargeAllocationFailureCallback afc, void* data);
5957 * Unlike the error reporter, which is only called if the exception for an OOM
5958 * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
5959 * at the OOM site to allow the embedding to capture the current state of heap
5960 * allocation before anything is freed. If the large-allocation-failure callback
5961 * is called at all (not all allocation sites call the large-allocation-failure
5962 * callback on failure), it is called before the out-of-memory callback; the
5963 * out-of-memory callback is only called if the allocation still fails after the
5964 * large-allocation-failure callback has returned.
5967 typedef void
5968 (* OutOfMemoryCallback)(JSContext* cx, void* data);
5970 extern JS_PUBLIC_API(void)
5971 SetOutOfMemoryCallback(JSRuntime* rt, OutOfMemoryCallback cb, void* data);
5975 * Capture the current call stack as a chain of SavedFrame JSObjects, and set
5976 * |stackp| to the SavedFrame for the youngest stack frame, or nullptr if there
5977 * are no JS frames on the stack. If |maxFrameCount| is non-zero, capture at
5978 * most the youngest |maxFrameCount| frames.
5980 extern JS_PUBLIC_API(bool)
5981 CaptureCurrentStack(JSContext* cx, MutableHandleObject stackp, unsigned maxFrameCount = 0);
5984 * This is a utility function for preparing an async stack to be used
5985 * by some other object. This may be used when you need to treat a
5986 * given stack trace as an async parent. If you just need to capture
5987 * the current stack, async parents and all, use CaptureCurrentStack
5988 * instead.
5990 * Here |asyncStack| is the async stack to prepare. It is copied into
5991 * |cx|'s current compartment, and the newest frame is given
5992 * |asyncCause| as its asynchronous cause. If |maxFrameCount| is
5993 * non-zero, capture at most the youngest |maxFrameCount| frames. The
5994 * new stack object is written to |stackp|. Returns true on success,
5995 * or sets an exception and returns |false| on error.
5997 extern JS_PUBLIC_API(bool)
5998 CopyAsyncStack(JSContext* cx, HandleObject asyncStack,
5999 HandleString asyncCause, MutableHandleObject stackp,
6000 unsigned maxFrameCount);
6003 * Accessors for working with SavedFrame JSObjects
6005 * Each of these functions assert that if their `HandleObject savedFrame`
6006 * argument is non-null, its JSClass is the SavedFrame class (or it is a
6007 * cross-compartment or Xray wrapper around an object with the SavedFrame class)
6008 * and the object is not the SavedFrame.prototype object.
6010 * Each of these functions will find the first SavedFrame object in the chain
6011 * whose underlying stack frame principals are subsumed by the cx's current
6012 * compartment's principals, and operate on that SavedFrame object. This
6013 * prevents leaking information about privileged frames to un-privileged
6014 * callers. As a result, the SavedFrame in parameters do _NOT_ need to be in the
6015 * same compartment as the cx, and the various out parameters are _NOT_
6016 * guaranteed to be in the same compartment as cx.
6018 * You may consider or skip over self-hosted frames by passing
6019 * `SavedFrameSelfHosted::Include` or `SavedFrameSelfHosted::Exclude`
6020 * respectively.
6022 * Additionally, it may be the case that there is no such SavedFrame object
6023 * whose captured frame's principals are subsumed by the caller's compartment's
6024 * principals! If the `HandleObject savedFrame` argument is null, or the
6025 * caller's principals do not subsume any of the chained SavedFrame object's
6026 * principals, `SavedFrameResult::AccessDenied` is returned and a (hopefully)
6027 * sane default value is chosen for the out param.
6029 * See also `js/src/doc/SavedFrame/SavedFrame.md`.
6032 enum class SavedFrameResult {
6034 AccessDenied
6037 enum class SavedFrameSelfHosted {
6038 Include,
6039 Exclude
6043 * Given a SavedFrame JSObject, get its source property. Defaults to the empty
6044 * string.
6046 extern JS_PUBLIC_API(SavedFrameResult)
6047 GetSavedFrameSource(JSContext* cx, HandleObject savedFrame, MutableHandleString sourcep,
6048 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6051 * Given a SavedFrame JSObject, get its line property. Defaults to 0.
6053 extern JS_PUBLIC_API(SavedFrameResult)
6054 GetSavedFrameLine(JSContext* cx, HandleObject savedFrame, uint32_t* linep,
6055 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6058 * Given a SavedFrame JSObject, get its column property. Defaults to 0.
6060 extern JS_PUBLIC_API(SavedFrameResult)
6061 GetSavedFrameColumn(JSContext* cx, HandleObject savedFrame, uint32_t* columnp,
6062 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6065 * Given a SavedFrame JSObject, get its functionDisplayName string, or nullptr
6066 * if SpiderMonkey was unable to infer a name for the captured frame's
6067 * function. Defaults to nullptr.
6069 extern JS_PUBLIC_API(SavedFrameResult)
6070 GetSavedFrameFunctionDisplayName(JSContext* cx, HandleObject savedFrame, MutableHandleString namep,
6071 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6074 * Given a SavedFrame JSObject, get its asyncCause string. Defaults to nullptr.
6076 extern JS_PUBLIC_API(SavedFrameResult)
6077 GetSavedFrameAsyncCause(JSContext* cx, HandleObject savedFrame, MutableHandleString asyncCausep,
6078 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6081 * Given a SavedFrame JSObject, get its asyncParent SavedFrame object or nullptr
6082 * if there is no asyncParent. The `asyncParentp` out parameter is _NOT_
6083 * guaranteed to be in the cx's compartment. Defaults to nullptr.
6085 extern JS_PUBLIC_API(SavedFrameResult)
6086 GetSavedFrameAsyncParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject asyncParentp,
6087 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6090 * Given a SavedFrame JSObject, get its parent SavedFrame object or nullptr if
6091 * it is the oldest frame in the stack. The `parentp` out parameter is _NOT_
6092 * guaranteed to be in the cx's compartment. Defaults to nullptr.
6094 extern JS_PUBLIC_API(SavedFrameResult)
6095 GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject parentp,
6096 SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
6099 * Given a SavedFrame JSObject stack, stringify it in the same format as
6100 * Error.prototype.stack. The stringified stack out parameter is placed in the
6101 * cx's compartment. Defaults to the empty string.
6103 * The same notes above about SavedFrame accessors applies here as well: cx
6104 * doesn't need to be in stack's compartment, and stack can be null, a
6105 * SavedFrame object, or a wrapper (CCW or Xray) around a SavedFrame object.
6107 * Optional indent parameter specifies the number of white spaces to indent
6108 * each line.
6110 extern JS_PUBLIC_API(bool)
6111 BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, size_t indent = 0);
6114 * Return true iff the given object is either a SavedFrame object or wrapper
6115 * around a SavedFrame object, and it is not the SavedFrame.prototype object.
6117 extern JS_PUBLIC_API(bool)
6118 IsSavedFrame(JSObject* obj);
6120 } /* namespace JS */
6123 /* Stopwatch-based performance monitoring. */
6125 namespace js {
6127 class AutoStopwatch;
6130 * Abstract base class for a representation of the performance of a
6131 * component. Embeddings interested in performance monitoring should
6132 * provide a concrete implementation of this class, as well as the
6133 * relevant callbacks (see below).
6135 struct PerformanceGroup {
6136 PerformanceGroup();
6138 // The current iteration of the event loop.
6139 uint64_t iteration() const;
6141 // `true` if an instance of `AutoStopwatch` is already monitoring
6142 // the performance of this performance group for this iteration
6143 // of the event loop, `false` otherwise.
6144 bool isAcquired(uint64_t it) const;
6146 // `true` if a specific instance of `AutoStopwatch` is already monitoring
6147 // the performance of this performance group for this iteration
6148 // of the event loop, `false` otherwise.
6149 bool isAcquired(uint64_t it, const AutoStopwatch* owner) const;
6151 // Mark that an instance of `AutoStopwatch` is monitoring
6152 // the performance of this group for a given iteration.
6153 void acquire(uint64_t it, const AutoStopwatch* owner);
6155 // Mark that no `AutoStopwatch` is monitoring the
6156 // performance of this group for the iteration.
6157 void release(uint64_t it, const AutoStopwatch* owner);
6159 // The number of cycles spent in this group during this iteration
6160 // of the event loop. Note that cycles are not a reliable measure,
6161 // especially over short intervals. See Stopwatch.* for a more
6162 // complete discussion on the imprecision of cycle measurement.
6163 uint64_t recentCycles(uint64_t iteration) const;
6164 void addRecentCycles(uint64_t iteration, uint64_t cycles);
6166 // The number of times this group has been activated during this
6167 // iteration of the event loop.
6168 uint64_t recentTicks(uint64_t iteration) const;
6169 void addRecentTicks(uint64_t iteration, uint64_t ticks);
6171 // The number of microseconds spent doing CPOW during this
6172 // iteration of the event loop.
6173 uint64_t recentCPOW(uint64_t iteration) const;
6174 void addRecentCPOW(uint64_t iteration, uint64_t CPOW);
6176 // Get rid of any data that pretends to be recent.
6177 void resetRecentData();
6179 // `true` if new measures should be added to this group, `false`
6180 // otherwise.
6181 bool isActive() const;
6182 void setIsActive(bool);
6184 // `true` if this group has been used in the current iteration,
6185 // `false` otherwise.
6186 bool isUsedInThisIteration() const;
6187 void setIsUsedInThisIteration(bool);
6188 protected:
6189 // An implementation of `delete` for this object. Must be provided
6190 // by the embedding.
6191 virtual void Delete() = 0;
6193 private:
6194 // The number of cycles spent in this group during this iteration
6195 // of the event loop. Note that cycles are not a reliable measure,
6196 // especially over short intervals. See Runtime.cpp for a more
6197 // complete discussion on the imprecision of cycle measurement.
6198 uint64_t recentCycles_;
6200 // The number of times this group has been activated during this
6201 // iteration of the event loop.
6202 uint64_t recentTicks_;
6204 // The number of microseconds spent doing CPOW during this
6205 // iteration of the event loop.
6206 uint64_t recentCPOW_;
6208 // The current iteration of the event loop. If necessary,
6209 // may safely overflow.
6210 uint64_t iteration_;
6212 // `true` if new measures should be added to this group, `false`
6213 // otherwise.
6214 bool isActive_;
6216 // `true` if this group has been used in the current iteration,
6217 // `false` otherwise.
6218 bool isUsedInThisIteration_;
6220 // The stopwatch currently monitoring the group,
6221 // or `nullptr` if none. Used ony for comparison.
6222 const AutoStopwatch* owner_;
6224 public:
6225 // Compatibility with RefPtr<>
6226 void AddRef();
6227 void Release();
6228 uint64_t refCount_;
6232 * Commit any Performance Monitoring data.
6234 * Until `FlushMonitoring` has been called, all PerformanceMonitoring data is invisible
6235 * to the outside world and can cancelled with a call to `ResetMonitoring`.
6237 extern JS_PUBLIC_API(bool)
6238 FlushPerformanceMonitoring(JSRuntime*);
6241 * Cancel any measurement that hasn't been committed.
6243 extern JS_PUBLIC_API(void)
6244 ResetPerformanceMonitoring(JSRuntime*);
6247 * Cleanup any memory used by performance monitoring.
6249 extern JS_PUBLIC_API(void)
6250 DisposePerformanceMonitoring(JSRuntime*);
6253 * Turn on/off stopwatch-based CPU monitoring.
6255 * `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank`
6256 * may return `false` if monitoring could not be activated, which may
6257 * happen if we are out of memory.
6259 extern JS_PUBLIC_API(bool)
6260 SetStopwatchIsMonitoringCPOW(JSRuntime*, bool);
6261 extern JS_PUBLIC_API(bool)
6262 GetStopwatchIsMonitoringCPOW(JSRuntime*);
6263 extern JS_PUBLIC_API(bool)
6264 SetStopwatchIsMonitoringJank(JSRuntime*, bool);
6265 extern JS_PUBLIC_API(bool)
6266 GetStopwatchIsMonitoringJank(JSRuntime*);
6268 extern JS_PUBLIC_API(bool)
6269 IsStopwatchActive(JSRuntime*);
6271 // Extract the CPU rescheduling data.
6272 extern JS_PUBLIC_API(void)
6273 GetPerfMonitoringTestCpuRescheduling(JSRuntime*, uint64_t* stayed, uint64_t* moved);
6277 * Add a number of microseconds to the time spent waiting on CPOWs
6278 * since process start.
6280 extern JS_PUBLIC_API(void)
6281 AddCPOWPerformanceDelta(JSRuntime*, uint64_t delta);
6283 typedef bool
6284 (*StopwatchStartCallback)(uint64_t, void*);
6285 extern JS_PUBLIC_API(bool)
6286 SetStopwatchStartCallback(JSRuntime*, StopwatchStartCallback, void*);
6288 typedef bool
6289 (*StopwatchCommitCallback)(uint64_t, mozilla::Vector<RefPtr<PerformanceGroup>>&, void*);
6290 extern JS_PUBLIC_API(bool)
6291 SetStopwatchCommitCallback(JSRuntime*, StopwatchCommitCallback, void*);
6293 typedef bool
6294 (*GetGroupsCallback)(JSContext*, mozilla::Vector<RefPtr<PerformanceGroup>>&, void*);
6295 extern JS_PUBLIC_API(bool)
6296 SetGetPerformanceGroupsCallback(JSRuntime*, GetGroupsCallback, void*);
6298 } /* namespace js */
6301 #endif /* jsapi_h */