Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/FloatingPoint.h"
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/RangedPtr.h"
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <stdio.h>
21 #include "jsalloc.h"
22 #include "jspubtd.h"
24 #include "js/CallArgs.h"
25 #include "js/Class.h"
26 #include "js/HashTable.h"
27 #include "js/Id.h"
28 #include "js/Principals.h"
29 #include "js/RootingAPI.h"
30 #include "js/TracingAPI.h"
31 #include "js/Utility.h"
32 #include "js/Value.h"
33 #include "js/Vector.h"
35 /************************************************************************/
37 namespace JS {
39 class Latin1CharsZ;
40 class TwoByteChars;
42 #if defined JS_THREADSAFE && defined JS_DEBUG
44 class JS_PUBLIC_API(AutoCheckRequestDepth)
45 {
46 JSContext *cx;
47 public:
48 AutoCheckRequestDepth(JSContext *cx);
49 AutoCheckRequestDepth(js::ContextFriendFields *cx);
50 ~AutoCheckRequestDepth();
51 };
53 # define CHECK_REQUEST(cx) \
54 JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
56 #else
58 # define CHECK_REQUEST(cx) \
59 ((void) 0)
61 #endif /* JS_THREADSAFE && JS_DEBUG */
63 #ifdef JS_DEBUG
64 /*
65 * Assert that we're not doing GC on cx, that we're in a request as
66 * needed, and that the compartments for cx and v are correct.
67 * Also check that GC would be safe at this point.
68 */
69 JS_PUBLIC_API(void)
70 AssertArgumentsAreSane(JSContext *cx, JS::HandleValue v);
71 #else
72 inline void AssertArgumentsAreSane(JSContext *cx, JS::HandleValue v) {
73 /* Do nothing */
74 }
75 #endif /* JS_DEBUG */
77 class JS_PUBLIC_API(AutoGCRooter) {
78 public:
79 AutoGCRooter(JSContext *cx, ptrdiff_t tag);
80 AutoGCRooter(js::ContextFriendFields *cx, ptrdiff_t tag);
82 ~AutoGCRooter() {
83 JS_ASSERT(this == *stackTop);
84 *stackTop = down;
85 }
87 /* Implemented in gc/RootMarking.cpp. */
88 inline void trace(JSTracer *trc);
89 static void traceAll(JSTracer *trc);
90 static void traceAllWrappers(JSTracer *trc);
92 protected:
93 AutoGCRooter * const down;
95 /*
96 * Discriminates actual subclass of this being used. If non-negative, the
97 * subclass roots an array of values of the length stored in this field.
98 * If negative, meaning is indicated by the corresponding value in the enum
99 * below. Any other negative value indicates some deeper problem such as
100 * memory corruption.
101 */
102 ptrdiff_t tag_;
104 enum {
105 VALARRAY = -2, /* js::AutoValueArray */
106 PARSER = -3, /* js::frontend::Parser */
107 SHAPEVECTOR = -4, /* js::AutoShapeVector */
108 IDARRAY = -6, /* js::AutoIdArray */
109 DESCRIPTORS = -7, /* js::AutoPropDescArrayRooter */
110 ID = -9, /* js::AutoIdRooter */
111 VALVECTOR = -10, /* js::AutoValueVector */
112 IDVECTOR = -13, /* js::AutoIdVector */
113 OBJVECTOR = -14, /* js::AutoObjectVector */
114 STRINGVECTOR =-15, /* js::AutoStringVector */
115 SCRIPTVECTOR =-16, /* js::AutoScriptVector */
116 NAMEVECTOR = -17, /* js::AutoNameVector */
117 HASHABLEVALUE=-18, /* js::HashableValue */
118 IONMASM = -19, /* js::jit::MacroAssembler */
119 IONALLOC = -20, /* js::jit::AutoTempAllocatorRooter */
120 WRAPVECTOR = -21, /* js::AutoWrapperVector */
121 WRAPPER = -22, /* js::AutoWrapperRooter */
122 OBJOBJHASHMAP=-23, /* js::AutoObjectObjectHashMap */
123 OBJU32HASHMAP=-24, /* js::AutoObjectUnsigned32HashMap */
124 OBJHASHSET = -25, /* js::AutoObjectHashSet */
125 JSONPARSER = -26, /* js::JSONParser */
126 CUSTOM = -27, /* js::CustomAutoRooter */
127 FUNVECTOR = -28 /* js::AutoFunctionVector */
128 };
130 private:
131 AutoGCRooter ** const stackTop;
133 /* No copy or assignment semantics. */
134 AutoGCRooter(AutoGCRooter &ida) MOZ_DELETE;
135 void operator=(AutoGCRooter &ida) MOZ_DELETE;
136 };
138 /* AutoValueArray roots an internal fixed-size array of Values. */
139 template <size_t N>
140 class AutoValueArray : public AutoGCRooter
141 {
142 const size_t length_;
143 Value elements_[N];
145 public:
146 AutoValueArray(JSContext *cx
147 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
148 : AutoGCRooter(cx, VALARRAY), length_(N)
149 {
150 /* Always initialize in case we GC before assignment. */
151 mozilla::PodArrayZero(elements_);
152 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
153 }
155 unsigned length() const { return length_; }
156 const Value *begin() const { return elements_; }
157 Value *begin() { return elements_; }
159 HandleValue operator[](unsigned i) const {
160 JS_ASSERT(i < N);
161 return HandleValue::fromMarkedLocation(&elements_[i]);
162 }
163 MutableHandleValue operator[](unsigned i) {
164 JS_ASSERT(i < N);
165 return MutableHandleValue::fromMarkedLocation(&elements_[i]);
166 }
168 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
169 };
171 template<class T>
172 class AutoVectorRooter : protected AutoGCRooter
173 {
174 typedef js::Vector<T, 8> VectorImpl;
175 VectorImpl vector;
177 public:
178 explicit AutoVectorRooter(JSContext *cx, ptrdiff_t tag
179 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
180 : AutoGCRooter(cx, tag), vector(cx)
181 {
182 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
183 }
185 explicit AutoVectorRooter(js::ContextFriendFields *cx, ptrdiff_t tag
186 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
187 : AutoGCRooter(cx, tag), vector(cx)
188 {
189 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
190 }
192 typedef T ElementType;
193 typedef typename VectorImpl::Range Range;
195 size_t length() const { return vector.length(); }
196 bool empty() const { return vector.empty(); }
198 bool append(const T &v) { return vector.append(v); }
199 bool append(const T *ptr, size_t len) { return vector.append(ptr, len); }
200 bool appendAll(const AutoVectorRooter<T> &other) {
201 return vector.appendAll(other.vector);
202 }
204 bool insert(T *p, const T &val) { return vector.insert(p, val); }
206 /* For use when space has already been reserved. */
207 void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
209 void popBack() { vector.popBack(); }
210 T popCopy() { return vector.popCopy(); }
212 bool growBy(size_t inc) {
213 size_t oldLength = vector.length();
214 if (!vector.growByUninitialized(inc))
215 return false;
216 makeRangeGCSafe(oldLength);
217 return true;
218 }
220 bool resize(size_t newLength) {
221 size_t oldLength = vector.length();
222 if (newLength <= oldLength) {
223 vector.shrinkBy(oldLength - newLength);
224 return true;
225 }
226 if (!vector.growByUninitialized(newLength - oldLength))
227 return false;
228 makeRangeGCSafe(oldLength);
229 return true;
230 }
232 void clear() { vector.clear(); }
234 bool reserve(size_t newLength) {
235 return vector.reserve(newLength);
236 }
238 T &operator[](size_t i) { return vector[i]; }
239 const T &operator[](size_t i) const { return vector[i]; }
241 JS::MutableHandle<T> handleAt(size_t i) {
242 return JS::MutableHandle<T>::fromMarkedLocation(&vector[i]);
243 }
244 JS::Handle<T> handleAt(size_t i) const {
245 return JS::Handle<T>::fromMarkedLocation(&vector[i]);
246 }
248 const T *begin() const { return vector.begin(); }
249 T *begin() { return vector.begin(); }
251 const T *end() const { return vector.end(); }
252 T *end() { return vector.end(); }
254 Range all() { return vector.all(); }
256 const T &back() const { return vector.back(); }
258 friend void AutoGCRooter::trace(JSTracer *trc);
260 private:
261 void makeRangeGCSafe(size_t oldLength) {
262 T *t = vector.begin() + oldLength;
263 for (size_t i = oldLength; i < vector.length(); ++i, ++t)
264 memset(t, 0, sizeof(T));
265 }
267 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
268 };
270 template<class Key, class Value>
271 class AutoHashMapRooter : protected AutoGCRooter
272 {
273 private:
274 typedef js::HashMap<Key, Value> HashMapImpl;
276 public:
277 explicit AutoHashMapRooter(JSContext *cx, ptrdiff_t tag
278 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
279 : AutoGCRooter(cx, tag), map(cx)
280 {
281 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
282 }
284 typedef Key KeyType;
285 typedef Value ValueType;
286 typedef typename HashMapImpl::Entry Entry;
287 typedef typename HashMapImpl::Lookup Lookup;
288 typedef typename HashMapImpl::Ptr Ptr;
289 typedef typename HashMapImpl::AddPtr AddPtr;
291 bool init(uint32_t len = 16) {
292 return map.init(len);
293 }
294 bool initialized() const {
295 return map.initialized();
296 }
297 Ptr lookup(const Lookup &l) const {
298 return map.lookup(l);
299 }
300 void remove(Ptr p) {
301 map.remove(p);
302 }
303 AddPtr lookupForAdd(const Lookup &l) const {
304 return map.lookupForAdd(l);
305 }
307 template<typename KeyInput, typename ValueInput>
308 bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) {
309 return map.add(p, k, v);
310 }
312 bool add(AddPtr &p, const Key &k) {
313 return map.add(p, k);
314 }
316 template<typename KeyInput, typename ValueInput>
317 bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) {
318 return map.relookupOrAdd(p, k, v);
319 }
321 typedef typename HashMapImpl::Range Range;
322 Range all() const {
323 return map.all();
324 }
326 typedef typename HashMapImpl::Enum Enum;
328 void clear() {
329 map.clear();
330 }
332 void finish() {
333 map.finish();
334 }
336 bool empty() const {
337 return map.empty();
338 }
340 uint32_t count() const {
341 return map.count();
342 }
344 size_t capacity() const {
345 return map.capacity();
346 }
348 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
349 return map.sizeOfExcludingThis(mallocSizeOf);
350 }
351 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
352 return map.sizeOfIncludingThis(mallocSizeOf);
353 }
355 unsigned generation() const {
356 return map.generation();
357 }
359 /************************************************** Shorthand operations */
361 bool has(const Lookup &l) const {
362 return map.has(l);
363 }
365 template<typename KeyInput, typename ValueInput>
366 bool put(const KeyInput &k, const ValueInput &v) {
367 return map.put(k, v);
368 }
370 template<typename KeyInput, typename ValueInput>
371 bool putNew(const KeyInput &k, const ValueInput &v) {
372 return map.putNew(k, v);
373 }
375 Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
376 return map.lookupWithDefault(k, defaultValue);
377 }
379 void remove(const Lookup &l) {
380 map.remove(l);
381 }
383 friend void AutoGCRooter::trace(JSTracer *trc);
385 private:
386 AutoHashMapRooter(const AutoHashMapRooter &hmr) MOZ_DELETE;
387 AutoHashMapRooter &operator=(const AutoHashMapRooter &hmr) MOZ_DELETE;
389 HashMapImpl map;
391 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
392 };
394 template<class T>
395 class AutoHashSetRooter : protected AutoGCRooter
396 {
397 private:
398 typedef js::HashSet<T> HashSetImpl;
400 public:
401 explicit AutoHashSetRooter(JSContext *cx, ptrdiff_t tag
402 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
403 : AutoGCRooter(cx, tag), set(cx)
404 {
405 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
406 }
408 typedef typename HashSetImpl::Lookup Lookup;
409 typedef typename HashSetImpl::Ptr Ptr;
410 typedef typename HashSetImpl::AddPtr AddPtr;
412 bool init(uint32_t len = 16) {
413 return set.init(len);
414 }
415 bool initialized() const {
416 return set.initialized();
417 }
418 Ptr lookup(const Lookup &l) const {
419 return set.lookup(l);
420 }
421 void remove(Ptr p) {
422 set.remove(p);
423 }
424 AddPtr lookupForAdd(const Lookup &l) const {
425 return set.lookupForAdd(l);
426 }
428 bool add(AddPtr &p, const T &t) {
429 return set.add(p, t);
430 }
432 bool relookupOrAdd(AddPtr &p, const Lookup &l, const T &t) {
433 return set.relookupOrAdd(p, l, t);
434 }
436 typedef typename HashSetImpl::Range Range;
437 Range all() const {
438 return set.all();
439 }
441 typedef typename HashSetImpl::Enum Enum;
443 void clear() {
444 set.clear();
445 }
447 void finish() {
448 set.finish();
449 }
451 bool empty() const {
452 return set.empty();
453 }
455 uint32_t count() const {
456 return set.count();
457 }
459 size_t capacity() const {
460 return set.capacity();
461 }
463 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
464 return set.sizeOfExcludingThis(mallocSizeOf);
465 }
466 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
467 return set.sizeOfIncludingThis(mallocSizeOf);
468 }
470 unsigned generation() const {
471 return set.generation();
472 }
474 /************************************************** Shorthand operations */
476 bool has(const Lookup &l) const {
477 return set.has(l);
478 }
480 bool put(const T &t) {
481 return set.put(t);
482 }
484 bool putNew(const T &t) {
485 return set.putNew(t);
486 }
488 void remove(const Lookup &l) {
489 set.remove(l);
490 }
492 friend void AutoGCRooter::trace(JSTracer *trc);
494 private:
495 AutoHashSetRooter(const AutoHashSetRooter &hmr) MOZ_DELETE;
496 AutoHashSetRooter &operator=(const AutoHashSetRooter &hmr) MOZ_DELETE;
498 HashSetImpl set;
500 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
501 };
503 class MOZ_STACK_CLASS AutoValueVector : public AutoVectorRooter<Value>
504 {
505 public:
506 explicit AutoValueVector(JSContext *cx
507 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
508 : AutoVectorRooter<Value>(cx, VALVECTOR)
509 {
510 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
511 }
513 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
514 };
516 class AutoIdVector : public AutoVectorRooter<jsid>
517 {
518 public:
519 explicit AutoIdVector(JSContext *cx
520 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
521 : AutoVectorRooter<jsid>(cx, IDVECTOR)
522 {
523 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
524 }
526 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
527 };
529 class AutoObjectVector : public AutoVectorRooter<JSObject *>
530 {
531 public:
532 explicit AutoObjectVector(JSContext *cx
533 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
534 : AutoVectorRooter<JSObject *>(cx, OBJVECTOR)
535 {
536 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
537 }
539 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
540 };
542 class AutoFunctionVector : public AutoVectorRooter<JSFunction *>
543 {
544 public:
545 explicit AutoFunctionVector(JSContext *cx
546 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
547 : AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
548 {
549 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
550 }
552 explicit AutoFunctionVector(js::ContextFriendFields *cx
553 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
554 : AutoVectorRooter<JSFunction *>(cx, FUNVECTOR)
555 {
556 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
557 }
559 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
560 };
562 class AutoScriptVector : public AutoVectorRooter<JSScript *>
563 {
564 public:
565 explicit AutoScriptVector(JSContext *cx
566 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
567 : AutoVectorRooter<JSScript *>(cx, SCRIPTVECTOR)
568 {
569 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
570 }
572 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
573 };
575 /*
576 * Cutsom rooting behavior for internal and external clients.
577 */
578 class JS_PUBLIC_API(CustomAutoRooter) : private AutoGCRooter
579 {
580 public:
581 template <typename CX>
582 explicit CustomAutoRooter(CX *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
583 : AutoGCRooter(cx, CUSTOM)
584 {
585 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
586 }
588 friend void AutoGCRooter::trace(JSTracer *trc);
590 protected:
591 /* Supplied by derived class to trace roots. */
592 virtual void trace(JSTracer *trc) = 0;
594 private:
595 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
596 };
598 /* A handle to an array of rooted values. */
599 class HandleValueArray
600 {
601 const size_t length_;
602 const Value * const elements_;
604 HandleValueArray(size_t len, const Value *elements) : length_(len), elements_(elements) {}
606 public:
607 HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
609 HandleValueArray(const AutoValueVector& values)
610 : length_(values.length()), elements_(values.begin()) {}
612 template <size_t N>
613 HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
615 /* CallArgs must already be rooted somewhere up the stack. */
616 HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
618 /* Use with care! Only call this if the data is guaranteed to be marked. */
619 static HandleValueArray fromMarkedLocation(size_t len, const Value *elements) {
620 return HandleValueArray(len, elements);
621 }
623 static HandleValueArray subarray(const HandleValueArray& values, size_t startIndex, size_t len) {
624 JS_ASSERT(startIndex + len <= values.length());
625 return HandleValueArray(len, values.begin() + startIndex);
626 }
628 static HandleValueArray empty() {
629 return HandleValueArray(0, nullptr);
630 }
632 size_t length() const { return length_; }
633 const Value *begin() const { return elements_; }
635 HandleValue operator[](size_t i) const {
636 JS_ASSERT(i < length_);
637 return HandleValue::fromMarkedLocation(&elements_[i]);
638 }
639 };
641 } /* namespace JS */
643 /************************************************************************/
645 struct JSFreeOp {
646 private:
647 JSRuntime *runtime_;
649 protected:
650 JSFreeOp(JSRuntime *rt)
651 : runtime_(rt) { }
653 public:
654 JSRuntime *runtime() const {
655 return runtime_;
656 }
657 };
659 /* Callbacks and their arguments. */
661 /************************************************************************/
663 typedef enum JSContextOp {
664 JSCONTEXT_NEW,
665 JSCONTEXT_DESTROY
666 } JSContextOp;
668 /*
669 * The possible values for contextOp when the runtime calls the callback are:
670 * JSCONTEXT_NEW JS_NewContext successfully created a new JSContext
671 * instance. The callback can initialize the instance as
672 * required. If the callback returns false, the instance
673 * will be destroyed and JS_NewContext returns null. In
674 * this case the callback is not called again.
675 * JSCONTEXT_DESTROY One of JS_DestroyContext* methods is called. The
676 * callback may perform its own cleanup and must always
677 * return true.
678 * Any other value For future compatibility the callback must do nothing
679 * and return true in this case.
680 */
681 typedef bool
682 (* JSContextCallback)(JSContext *cx, unsigned contextOp, void *data);
684 typedef enum JSGCStatus {
685 JSGC_BEGIN,
686 JSGC_END
687 } JSGCStatus;
689 typedef void
690 (* JSGCCallback)(JSRuntime *rt, JSGCStatus status, void *data);
692 typedef enum JSFinalizeStatus {
693 /*
694 * Called when preparing to sweep a group of compartments, before anything
695 * has been swept. The collector will not yield to the mutator before
696 * calling the callback with JSFINALIZE_GROUP_END status.
697 */
698 JSFINALIZE_GROUP_START,
700 /*
701 * Called when preparing to sweep a group of compartments. Weak references
702 * to unmarked things have been removed and things that are not swept
703 * incrementally have been finalized at this point. The collector may yield
704 * to the mutator after this point.
705 */
706 JSFINALIZE_GROUP_END,
708 /*
709 * Called at the end of collection when everything has been swept.
710 */
711 JSFINALIZE_COLLECTION_END
712 } JSFinalizeStatus;
714 typedef void
715 (* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment);
717 typedef bool
718 (* JSInterruptCallback)(JSContext *cx);
720 typedef void
721 (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
723 #ifdef MOZ_TRACE_JSCALLS
724 typedef void
725 (* JSFunctionCallback)(const JSFunction *fun,
726 const JSScript *scr,
727 const JSContext *cx,
728 int entering);
729 #endif
731 /*
732 * Possible exception types. These types are part of a JSErrorFormatString
733 * structure. They define which error to throw in case of a runtime error.
734 * JSEXN_NONE marks an unthrowable error.
735 */
736 typedef enum JSExnType {
737 JSEXN_NONE = -1,
738 JSEXN_ERR,
739 JSEXN_INTERNALERR,
740 JSEXN_EVALERR,
741 JSEXN_RANGEERR,
742 JSEXN_REFERENCEERR,
743 JSEXN_SYNTAXERR,
744 JSEXN_TYPEERR,
745 JSEXN_URIERR,
746 JSEXN_LIMIT
747 } JSExnType;
749 typedef struct JSErrorFormatString {
750 /* The error format string in ASCII. */
751 const char *format;
753 /* The number of arguments to expand in the formatted error message. */
754 uint16_t argCount;
756 /* One of the JSExnType constants above. */
757 int16_t exnType;
758 } JSErrorFormatString;
760 typedef const JSErrorFormatString *
761 (* JSErrorCallback)(void *userRef, const char *locale,
762 const unsigned errorNumber);
764 typedef bool
765 (* JSLocaleToUpperCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
767 typedef bool
768 (* JSLocaleToLowerCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
770 typedef bool
771 (* JSLocaleCompare)(JSContext *cx, JS::HandleString src1, JS::HandleString src2,
772 JS::MutableHandleValue rval);
774 typedef bool
775 (* JSLocaleToUnicode)(JSContext *cx, const char *src, JS::MutableHandleValue rval);
777 /*
778 * Callback used to ask the embedding for the cross compartment wrapper handler
779 * that implements the desired prolicy for this kind of object in the
780 * destination compartment. |obj| is the object to be wrapped. If |existing| is
781 * non-nullptr, it will point to an existing wrapper object that should be
782 * re-used if possible. |existing| is guaranteed to be a cross-compartment
783 * wrapper with a lazily-defined prototype and the correct global. It is
784 * guaranteed not to wrap a function.
785 */
786 typedef JSObject *
787 (* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj,
788 JS::HandleObject proto, JS::HandleObject parent,
789 unsigned flags);
791 /*
792 * Callback used by the wrap hook to ask the embedding to prepare an object
793 * for wrapping in a context. This might include unwrapping other wrappers
794 * or even finding a more suitable object for the new compartment.
795 */
796 typedef JSObject *
797 (* JSPreWrapCallback)(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj,
798 unsigned flags);
800 struct JSWrapObjectCallbacks
801 {
802 JSWrapObjectCallback wrap;
803 JSPreWrapCallback preWrap;
804 };
806 typedef void
807 (* JSDestroyCompartmentCallback)(JSFreeOp *fop, JSCompartment *compartment);
809 typedef void
810 (* JSZoneCallback)(JS::Zone *zone);
812 typedef void
813 (* JSCompartmentNameCallback)(JSRuntime *rt, JSCompartment *compartment,
814 char *buf, size_t bufsize);
816 /************************************************************************/
818 static MOZ_ALWAYS_INLINE jsval
819 JS_NumberValue(double d)
820 {
821 int32_t i;
822 d = JS::CanonicalizeNaN(d);
823 if (mozilla::NumberIsInt32(d, &i))
824 return INT_TO_JSVAL(i);
825 return DOUBLE_TO_JSVAL(d);
826 }
828 /************************************************************************/
830 JS_PUBLIC_API(bool)
831 JS_StringHasBeenInterned(JSContext *cx, JSString *str);
833 /*
834 * Only JSStrings that have been interned via the JSAPI can be turned into
835 * jsids by API clients.
836 *
837 * N.B. if a jsid is backed by a string which has not been interned, that
838 * string must be appropriately rooted to avoid being collected by the GC.
839 */
840 JS_PUBLIC_API(jsid)
841 INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str);
843 /*
844 * Returns true iff the given jsval is immune to GC and can be used across
845 * multiple JSRuntimes without requiring any conversion API.
846 */
847 static MOZ_ALWAYS_INLINE bool
848 JSVAL_IS_UNIVERSAL(jsval v)
849 {
850 return !JSVAL_IS_GCTHING(v);
851 }
853 namespace JS {
855 class AutoIdRooter : private AutoGCRooter
856 {
857 public:
858 explicit AutoIdRooter(JSContext *cx, jsid aId = INT_TO_JSID(0)
859 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
860 : AutoGCRooter(cx, ID), id_(aId)
861 {
862 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
863 }
865 jsid id() {
866 return id_;
867 }
869 jsid * addr() {
870 return &id_;
871 }
873 friend void AutoGCRooter::trace(JSTracer *trc);
875 private:
876 jsid id_;
877 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
878 };
880 // Container class for passing in script source buffers to the JS engine. This
881 // not only groups the buffer and length values, it also provides a way to
882 // optionally pass ownership of the buffer to the JS engine without copying.
883 // Rules for use:
884 //
885 // 1) The data array must be allocated with js_malloc() or js_realloc() if
886 // ownership is being granted to the SourceBufferHolder.
887 // 2) If ownership is not given to the SourceBufferHolder, then the memory
888 // must be kept alive until the JS compilation is complete.
889 // 3) Any code calling SourceBufferHolder::take() must guarantee to keep the
890 // memory alive until JS compilation completes. Normally only the JS
891 // engine should be calling take().
892 //
893 // Example use:
894 //
895 // size_t length = 512;
896 // jschar* chars = static_cast<jschar*>(js_malloc(sizeof(jschar) * length));
897 // JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
898 // JS::Compile(cx, obj, options, srcBuf);
899 //
900 class MOZ_STACK_CLASS SourceBufferHolder MOZ_FINAL
901 {
902 public:
903 enum Ownership {
904 NoOwnership,
905 GiveOwnership
906 };
908 SourceBufferHolder(const jschar *data, size_t dataLength, Ownership ownership)
909 : data_(data),
910 length_(dataLength),
911 ownsChars_(ownership == GiveOwnership)
912 {
913 // Ensure that null buffers properly return an unowned, empty,
914 // null-terminated string.
915 static const jschar NullChar_ = 0;
916 if (!get()) {
917 data_ = &NullChar_;
918 length_ = 0;
919 ownsChars_ = false;
920 }
921 }
923 ~SourceBufferHolder() {
924 if (ownsChars_)
925 js_free(const_cast<jschar *>(data_));
926 }
928 // Access the underlying source buffer without affecting ownership.
929 const jschar *get() const { return data_; }
931 // Length of the source buffer in jschars (not bytes)
932 size_t length() const { return length_; }
934 // Returns true if the SourceBufferHolder owns the buffer and will free
935 // it upon destruction. If true, it is legal to call take().
936 bool ownsChars() const { return ownsChars_; }
938 // Retrieve and take ownership of the underlying data buffer. The caller
939 // is now responsible for calling js_free() on the returned value, *but only
940 // after JS script compilation has completed*.
941 //
942 // After the buffer has been taken the SourceBufferHolder functions as if
943 // it had been constructed on an unowned buffer; get() and length() still
944 // work. In order for this to be safe the taken buffer must be kept alive
945 // until after JS script compilation completes as noted above.
946 //
947 // Note, it's the caller's responsibility to check ownsChars() before taking
948 // the buffer. Taking and then free'ing an unowned buffer will have dire
949 // consequences.
950 jschar *take() {
951 JS_ASSERT(ownsChars_);
952 ownsChars_ = false;
953 return const_cast<jschar *>(data_);
954 }
956 private:
957 SourceBufferHolder(SourceBufferHolder &) MOZ_DELETE;
958 SourceBufferHolder &operator=(SourceBufferHolder &) MOZ_DELETE;
960 const jschar *data_;
961 size_t length_;
962 bool ownsChars_;
963 };
965 } /* namespace JS */
967 /************************************************************************/
969 /* Property attributes, set in JSPropertySpec and passed to API functions. */
970 #define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */
971 #define JSPROP_READONLY 0x02 /* not settable: assignment is no-op.
972 This flag is only valid when neither
973 JSPROP_GETTER nor JSPROP_SETTER is
974 set. */
975 #define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
976 #define JSPROP_NATIVE_ACCESSORS 0x08 /* set in JSPropertyDescriptor.flags
977 if getters/setters are JSNatives */
978 #define JSPROP_GETTER 0x10 /* property holds getter function */
979 #define JSPROP_SETTER 0x20 /* property holds setter function */
980 #define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
981 property; don't copy the property on
982 set of the same-named property in an
983 object that delegates to a prototype
984 containing this property */
985 #define JSPROP_INDEX 0x80 /* name is actually (int) index */
987 #define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
988 instead of defaulting to class gsops
989 for property holding function */
991 #define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
994 /*
995 * Specify a generic native prototype methods, i.e., methods of a class
996 * prototype that are exposed as static methods taking an extra leading
997 * argument: the generic |this| parameter.
998 *
999 * If you set this flag in a JSFunctionSpec struct's flags initializer, then
1000 * that struct must live at least as long as the native static method object
1001 * created due to this flag by JS_DefineFunctions or JS_InitClass. Typically
1002 * JSFunctionSpec structs are allocated in static arrays.
1003 */
1004 #define JSFUN_GENERIC_NATIVE 0x800
1006 #define JSFUN_FLAGS_MASK 0xe00 /* | of all the JSFUN_* flags */
1008 /*
1009 * The first call to JS_CallOnce by any thread in a process will call 'func'.
1010 * Later calls to JS_CallOnce with the same JSCallOnceType object will be
1011 * suppressed.
1012 *
1013 * Equivalently: each distinct JSCallOnceType object will allow one JS_CallOnce
1014 * to invoke its JSInitCallback.
1015 */
1016 extern JS_PUBLIC_API(bool)
1017 JS_CallOnce(JSCallOnceType *once, JSInitCallback func);
1019 /* Microseconds since the epoch, midnight, January 1, 1970 UTC. */
1020 extern JS_PUBLIC_API(int64_t)
1021 JS_Now(void);
1023 /* Don't want to export data, so provide accessors for non-inline jsvals. */
1024 extern JS_PUBLIC_API(jsval)
1025 JS_GetNaNValue(JSContext *cx);
1027 extern JS_PUBLIC_API(jsval)
1028 JS_GetNegativeInfinityValue(JSContext *cx);
1030 extern JS_PUBLIC_API(jsval)
1031 JS_GetPositiveInfinityValue(JSContext *cx);
1033 extern JS_PUBLIC_API(jsval)
1034 JS_GetEmptyStringValue(JSContext *cx);
1036 extern JS_PUBLIC_API(JSString *)
1037 JS_GetEmptyString(JSRuntime *rt);
1039 /*
1040 * Format is a string of the following characters (spaces are insignificant),
1041 * specifying the tabulated type conversions:
1042 *
1043 * b bool Boolean
1044 * c uint16_t/jschar ECMA uint16_t, Unicode char
1045 * i int32_t ECMA int32_t
1046 * j int32_t ECMA int32_t (used to be different)
1047 * u uint32_t ECMA uint32_t
1048 * d double IEEE double
1049 * I double Integral IEEE double
1050 * S JSString * Unicode string, accessed by a JSString pointer
1051 * W jschar * Unicode character vector, 0-terminated (W for wide)
1052 * o JSObject * Object reference
1053 * f JSFunction * Function private
1054 * v jsval Argument value (no conversion)
1055 * * N/A Skip this argument (no vararg)
1056 * / N/A End of required arguments
1057 *
1058 * The variable argument list after format must consist of &b, &c, &s, e.g.,
1059 * where those variables have the types given above. For the pointer types
1060 * char *, JSString *, and JSObject *, the pointed-at memory returned belongs
1061 * to the JS runtime, not to the calling native code. The runtime promises
1062 * to keep this memory valid so long as argv refers to allocated stack space
1063 * (so long as the native function is active).
1064 *
1065 * Fewer arguments than format specifies may be passed only if there is a /
1066 * in format after the last required argument specifier and argc is at least
1067 * the number of required arguments. More arguments than format specifies
1068 * may be passed without error; it is up to the caller to deal with trailing
1069 * unconverted arguments.
1070 */
1071 extern JS_PUBLIC_API(bool)
1072 JS_ConvertArguments(JSContext *cx, const JS::CallArgs &args, const char *format, ...);
1074 #ifdef va_start
1075 extern JS_PUBLIC_API(bool)
1076 JS_ConvertArgumentsVA(JSContext *cx, const JS::CallArgs &args, const char *format,
1077 va_list ap);
1078 #endif
1080 extern JS_PUBLIC_API(bool)
1081 JS_ConvertValue(JSContext *cx, JS::HandleValue v, JSType type, JS::MutableHandleValue vp);
1083 extern JS_PUBLIC_API(bool)
1084 JS_ValueToObject(JSContext *cx, JS::HandleValue v, JS::MutableHandleObject objp);
1086 extern JS_PUBLIC_API(JSFunction *)
1087 JS_ValueToFunction(JSContext *cx, JS::HandleValue v);
1089 extern JS_PUBLIC_API(JSFunction *)
1090 JS_ValueToConstructor(JSContext *cx, JS::HandleValue v);
1092 extern JS_PUBLIC_API(JSString *)
1093 JS_ValueToSource(JSContext *cx, JS::Handle<JS::Value> v);
1095 namespace js {
1096 /*
1097 * DO NOT CALL THIS. Use JS::ToNumber
1098 */
1099 extern JS_PUBLIC_API(bool)
1100 ToNumberSlow(JSContext *cx, JS::Value v, double *dp);
1102 /*
1103 * DO NOT CALL THIS. Use JS::ToBoolean
1104 */
1105 extern JS_PUBLIC_API(bool)
1106 ToBooleanSlow(JS::HandleValue v);
1108 /*
1109 * DO NOT CALL THIS. Use JS::ToString
1110 */
1111 extern JS_PUBLIC_API(JSString*)
1112 ToStringSlow(JSContext *cx, JS::HandleValue v);
1113 } /* namespace js */
1115 namespace JS {
1117 /* ES5 9.3 ToNumber. */
1118 MOZ_ALWAYS_INLINE bool
1119 ToNumber(JSContext *cx, HandleValue v, double *out)
1120 {
1121 AssertArgumentsAreSane(cx, v);
1123 if (v.isNumber()) {
1124 *out = v.toNumber();
1125 return true;
1126 }
1127 return js::ToNumberSlow(cx, v, out);
1128 }
1130 MOZ_ALWAYS_INLINE bool
1131 ToBoolean(HandleValue v)
1132 {
1133 if (v.isBoolean())
1134 return v.toBoolean();
1135 if (v.isInt32())
1136 return v.toInt32() != 0;
1137 if (v.isNullOrUndefined())
1138 return false;
1139 if (v.isDouble()) {
1140 double d = v.toDouble();
1141 return !mozilla::IsNaN(d) && d != 0;
1142 }
1144 /* The slow path handles strings and objects. */
1145 return js::ToBooleanSlow(v);
1146 }
1148 MOZ_ALWAYS_INLINE JSString*
1149 ToString(JSContext *cx, HandleValue v)
1150 {
1151 if (v.isString())
1152 return v.toString();
1153 return js::ToStringSlow(cx, v);
1154 }
1156 } /* namespace JS */
1158 extern JS_PUBLIC_API(bool)
1159 JS_DoubleIsInt32(double d, int32_t *ip);
1161 extern JS_PUBLIC_API(int32_t)
1162 JS_DoubleToInt32(double d);
1164 extern JS_PUBLIC_API(uint32_t)
1165 JS_DoubleToUint32(double d);
1168 namespace js {
1169 /* DO NOT CALL THIS. Use JS::ToUint16. */
1170 extern JS_PUBLIC_API(bool)
1171 ToUint16Slow(JSContext *cx, JS::HandleValue v, uint16_t *out);
1173 /* DO NOT CALL THIS. Use JS::ToInt32. */
1174 extern JS_PUBLIC_API(bool)
1175 ToInt32Slow(JSContext *cx, JS::HandleValue v, int32_t *out);
1177 /* DO NOT CALL THIS. Use JS::ToUint32. */
1178 extern JS_PUBLIC_API(bool)
1179 ToUint32Slow(JSContext *cx, JS::HandleValue v, uint32_t *out);
1181 /* DO NOT CALL THIS. Use JS::ToInt64. */
1182 extern JS_PUBLIC_API(bool)
1183 ToInt64Slow(JSContext *cx, JS::HandleValue v, int64_t *out);
1185 /* DO NOT CALL THIS. Use JS::ToUint64. */
1186 extern JS_PUBLIC_API(bool)
1187 ToUint64Slow(JSContext *cx, JS::HandleValue v, uint64_t *out);
1188 } /* namespace js */
1190 namespace JS {
1192 MOZ_ALWAYS_INLINE bool
1193 ToUint16(JSContext *cx, JS::HandleValue v, uint16_t *out)
1194 {
1195 AssertArgumentsAreSane(cx, v);
1197 if (v.isInt32()) {
1198 *out = uint16_t(v.toInt32());
1199 return true;
1200 }
1201 return js::ToUint16Slow(cx, v, out);
1202 }
1204 MOZ_ALWAYS_INLINE bool
1205 ToInt32(JSContext *cx, JS::HandleValue v, int32_t *out)
1206 {
1207 AssertArgumentsAreSane(cx, v);
1209 if (v.isInt32()) {
1210 *out = v.toInt32();
1211 return true;
1212 }
1213 return js::ToInt32Slow(cx, v, out);
1214 }
1216 MOZ_ALWAYS_INLINE bool
1217 ToUint32(JSContext *cx, JS::HandleValue v, uint32_t *out)
1218 {
1219 AssertArgumentsAreSane(cx, v);
1221 if (v.isInt32()) {
1222 *out = uint32_t(v.toInt32());
1223 return true;
1224 }
1225 return js::ToUint32Slow(cx, v, out);
1226 }
1228 MOZ_ALWAYS_INLINE bool
1229 ToInt64(JSContext *cx, JS::HandleValue v, int64_t *out)
1230 {
1231 AssertArgumentsAreSane(cx, v);
1233 if (v.isInt32()) {
1234 *out = int64_t(v.toInt32());
1235 return true;
1236 }
1237 return js::ToInt64Slow(cx, v, out);
1238 }
1240 MOZ_ALWAYS_INLINE bool
1241 ToUint64(JSContext *cx, JS::HandleValue v, uint64_t *out)
1242 {
1243 AssertArgumentsAreSane(cx, v);
1245 if (v.isInt32()) {
1246 /* Account for sign extension of negatives into the longer 64bit space. */
1247 *out = uint64_t(int64_t(v.toInt32()));
1248 return true;
1249 }
1250 return js::ToUint64Slow(cx, v, out);
1251 }
1254 } /* namespace JS */
1256 extern JS_PUBLIC_API(JSType)
1257 JS_TypeOfValue(JSContext *cx, JS::Handle<JS::Value> v);
1259 extern JS_PUBLIC_API(const char *)
1260 JS_GetTypeName(JSContext *cx, JSType type);
1262 extern JS_PUBLIC_API(bool)
1263 JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, bool *equal);
1265 extern JS_PUBLIC_API(bool)
1266 JS_LooselyEqual(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *equal);
1268 extern JS_PUBLIC_API(bool)
1269 JS_SameValue(JSContext *cx, jsval v1, jsval v2, bool *same);
1271 /* True iff fun is the global eval function. */
1272 extern JS_PUBLIC_API(bool)
1273 JS_IsBuiltinEvalFunction(JSFunction *fun);
1275 /* True iff fun is the Function constructor. */
1276 extern JS_PUBLIC_API(bool)
1277 JS_IsBuiltinFunctionConstructor(JSFunction *fun);
1279 /************************************************************************/
1281 /*
1282 * Initialization, locking, contexts, and memory allocation.
1283 *
1284 * It is important that the first runtime and first context be created in a
1285 * single-threaded fashion, otherwise the behavior of the library is undefined.
1286 * See: http://developer.mozilla.org/en/docs/Category:JSAPI_Reference
1287 */
1289 typedef enum JSUseHelperThreads
1290 {
1291 JS_NO_HELPER_THREADS,
1292 JS_USE_HELPER_THREADS
1293 } JSUseHelperThreads;
1295 /**
1296 * Initialize SpiderMonkey, returning true only if initialization succeeded.
1297 * Once this method has succeeded, it is safe to call JS_NewRuntime and other
1298 * JSAPI methods.
1299 *
1300 * This method must be called before any other JSAPI method is used on any
1301 * thread. Once it has been used, it is safe to call any JSAPI method, and it
1302 * remains safe to do so until JS_ShutDown is correctly called.
1303 *
1304 * It is currently not possible to initialize SpiderMonkey multiple times (that
1305 * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
1306 * again). This restriction may eventually be lifted.
1307 */
1308 extern JS_PUBLIC_API(bool)
1309 JS_Init(void);
1311 /**
1312 * Destroy free-standing resources allocated by SpiderMonkey, not associated
1313 * with any runtime, context, or other structure.
1314 *
1315 * This method should be called after all other JSAPI data has been properly
1316 * cleaned up: every new runtime must have been destroyed, every new context
1317 * must have been destroyed, and so on. Calling this method before all other
1318 * resources have been destroyed has undefined behavior.
1319 *
1320 * Failure to call this method, at present, has no adverse effects other than
1321 * leaking memory. This may not always be the case; it's recommended that all
1322 * embedders call this method when all other JSAPI operations have completed.
1323 *
1324 * It is currently not possible to initialize SpiderMonkey multiple times (that
1325 * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
1326 * again). This restriction may eventually be lifted.
1327 */
1328 extern JS_PUBLIC_API(void)
1329 JS_ShutDown(void);
1331 extern JS_PUBLIC_API(JSRuntime *)
1332 JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads,
1333 JSRuntime *parentRuntime = nullptr);
1335 extern JS_PUBLIC_API(void)
1336 JS_DestroyRuntime(JSRuntime *rt);
1338 // These are equivalent to ICU's |UMemAllocFn|, |UMemReallocFn|, and
1339 // |UMemFreeFn| types. The first argument (called |context| in the ICU docs)
1340 // will always be nullptr, and should be ignored.
1341 typedef void *(*JS_ICUAllocFn)(const void *, size_t size);
1342 typedef void *(*JS_ICUReallocFn)(const void *, void *p, size_t size);
1343 typedef void (*JS_ICUFreeFn)(const void *, void *p);
1345 // This function can be used to track memory used by ICU.
1346 // Do not use it unless you know what you are doing!
1347 extern JS_PUBLIC_API(bool)
1348 JS_SetICUMemoryFunctions(JS_ICUAllocFn allocFn, JS_ICUReallocFn reallocFn, JS_ICUFreeFn freeFn);
1350 JS_PUBLIC_API(void *)
1351 JS_GetRuntimePrivate(JSRuntime *rt);
1353 extern JS_PUBLIC_API(JSRuntime *)
1354 JS_GetRuntime(JSContext *cx);
1356 extern JS_PUBLIC_API(JSRuntime *)
1357 JS_GetParentRuntime(JSContext *cx);
1359 JS_PUBLIC_API(void)
1360 JS_SetRuntimePrivate(JSRuntime *rt, void *data);
1362 extern JS_PUBLIC_API(void)
1363 JS_BeginRequest(JSContext *cx);
1365 extern JS_PUBLIC_API(void)
1366 JS_EndRequest(JSContext *cx);
1368 extern JS_PUBLIC_API(bool)
1369 JS_IsInRequest(JSRuntime *rt);
1371 namespace js {
1373 void
1374 AssertHeapIsIdle(JSRuntime *rt);
1376 void
1377 AssertHeapIsIdle(JSContext *cx);
1379 } /* namespace js */
1381 class JSAutoRequest
1382 {
1383 public:
1384 JSAutoRequest(JSContext *cx
1385 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
1386 : mContext(cx)
1387 {
1388 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
1389 JS_BeginRequest(mContext);
1390 }
1391 ~JSAutoRequest() {
1392 JS_EndRequest(mContext);
1393 }
1395 protected:
1396 JSContext *mContext;
1397 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1399 #if 0
1400 private:
1401 static void *operator new(size_t) CPP_THROW_NEW { return 0; };
1402 static void operator delete(void *, size_t) { };
1403 #endif
1404 };
1406 class JSAutoCheckRequest
1407 {
1408 public:
1409 JSAutoCheckRequest(JSContext *cx
1410 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
1411 {
1412 #if defined JS_THREADSAFE && defined JS_DEBUG
1413 mContext = cx;
1414 JS_ASSERT(JS_IsInRequest(JS_GetRuntime(cx)));
1415 #endif
1416 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
1417 }
1419 ~JSAutoCheckRequest() {
1420 #if defined JS_THREADSAFE && defined JS_DEBUG
1421 JS_ASSERT(JS_IsInRequest(JS_GetRuntime(mContext)));
1422 #endif
1423 }
1426 private:
1427 #if defined JS_THREADSAFE && defined JS_DEBUG
1428 JSContext *mContext;
1429 #endif
1430 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1431 };
1433 extern JS_PUBLIC_API(void)
1434 JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback, void *data);
1436 extern JS_PUBLIC_API(JSContext *)
1437 JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
1439 extern JS_PUBLIC_API(void)
1440 JS_DestroyContext(JSContext *cx);
1442 extern JS_PUBLIC_API(void)
1443 JS_DestroyContextNoGC(JSContext *cx);
1445 extern JS_PUBLIC_API(void *)
1446 JS_GetContextPrivate(JSContext *cx);
1448 extern JS_PUBLIC_API(void)
1449 JS_SetContextPrivate(JSContext *cx, void *data);
1451 extern JS_PUBLIC_API(void *)
1452 JS_GetSecondContextPrivate(JSContext *cx);
1454 extern JS_PUBLIC_API(void)
1455 JS_SetSecondContextPrivate(JSContext *cx, void *data);
1457 extern JS_PUBLIC_API(JSRuntime *)
1458 JS_GetRuntime(JSContext *cx);
1460 extern JS_PUBLIC_API(JSContext *)
1461 JS_ContextIterator(JSRuntime *rt, JSContext **iterp);
1463 extern JS_PUBLIC_API(JSVersion)
1464 JS_GetVersion(JSContext *cx);
1466 // Mutate the version on the compartment. This is generally discouraged, but
1467 // necessary to support the version mutation in the js and xpc shell command
1468 // set.
1469 //
1470 // It would be nice to put this in jsfriendapi, but the linkage requirements
1471 // of the shells make that impossible.
1472 JS_PUBLIC_API(void)
1473 JS_SetVersionForCompartment(JSCompartment *compartment, JSVersion version);
1475 extern JS_PUBLIC_API(const char *)
1476 JS_VersionToString(JSVersion version);
1478 extern JS_PUBLIC_API(JSVersion)
1479 JS_StringToVersion(const char *string);
1481 namespace JS {
1483 class JS_PUBLIC_API(RuntimeOptions) {
1484 public:
1485 RuntimeOptions()
1486 : baseline_(false),
1487 ion_(false),
1488 asmJS_(false)
1489 {
1490 }
1492 bool baseline() const { return baseline_; }
1493 RuntimeOptions &setBaseline(bool flag) {
1494 baseline_ = flag;
1495 return *this;
1496 }
1497 RuntimeOptions &toggleBaseline() {
1498 baseline_ = !baseline_;
1499 return *this;
1500 }
1502 bool ion() const { return ion_; }
1503 RuntimeOptions &setIon(bool flag) {
1504 ion_ = flag;
1505 return *this;
1506 }
1507 RuntimeOptions &toggleIon() {
1508 ion_ = !ion_;
1509 return *this;
1510 }
1512 bool asmJS() const { return asmJS_; }
1513 RuntimeOptions &setAsmJS(bool flag) {
1514 asmJS_ = flag;
1515 return *this;
1516 }
1517 RuntimeOptions &toggleAsmJS() {
1518 asmJS_ = !asmJS_;
1519 return *this;
1520 }
1522 private:
1523 bool baseline_ : 1;
1524 bool ion_ : 1;
1525 bool asmJS_ : 1;
1526 };
1528 JS_PUBLIC_API(RuntimeOptions &)
1529 RuntimeOptionsRef(JSRuntime *rt);
1531 JS_PUBLIC_API(RuntimeOptions &)
1532 RuntimeOptionsRef(JSContext *cx);
1534 class JS_PUBLIC_API(ContextOptions) {
1535 public:
1536 ContextOptions()
1537 : extraWarnings_(false),
1538 werror_(false),
1539 varObjFix_(false),
1540 privateIsNSISupports_(false),
1541 dontReportUncaught_(false),
1542 noDefaultCompartmentObject_(false),
1543 noScriptRval_(false),
1544 strictMode_(false),
1545 cloneSingletons_(false)
1546 {
1547 }
1549 bool extraWarnings() const { return extraWarnings_; }
1550 ContextOptions &setExtraWarnings(bool flag) {
1551 extraWarnings_ = flag;
1552 return *this;
1553 }
1554 ContextOptions &toggleExtraWarnings() {
1555 extraWarnings_ = !extraWarnings_;
1556 return *this;
1557 }
1559 bool werror() const { return werror_; }
1560 ContextOptions &setWerror(bool flag) {
1561 werror_ = flag;
1562 return *this;
1563 }
1564 ContextOptions &toggleWerror() {
1565 werror_ = !werror_;
1566 return *this;
1567 }
1569 bool varObjFix() const { return varObjFix_; }
1570 ContextOptions &setVarObjFix(bool flag) {
1571 varObjFix_ = flag;
1572 return *this;
1573 }
1574 ContextOptions &toggleVarObjFix() {
1575 varObjFix_ = !varObjFix_;
1576 return *this;
1577 }
1579 bool privateIsNSISupports() const { return privateIsNSISupports_; }
1580 ContextOptions &setPrivateIsNSISupports(bool flag) {
1581 privateIsNSISupports_ = flag;
1582 return *this;
1583 }
1584 ContextOptions &togglePrivateIsNSISupports() {
1585 privateIsNSISupports_ = !privateIsNSISupports_;
1586 return *this;
1587 }
1589 bool dontReportUncaught() const { return dontReportUncaught_; }
1590 ContextOptions &setDontReportUncaught(bool flag) {
1591 dontReportUncaught_ = flag;
1592 return *this;
1593 }
1594 ContextOptions &toggleDontReportUncaught() {
1595 dontReportUncaught_ = !dontReportUncaught_;
1596 return *this;
1597 }
1599 bool noDefaultCompartmentObject() const { return noDefaultCompartmentObject_; }
1600 ContextOptions &setNoDefaultCompartmentObject(bool flag) {
1601 noDefaultCompartmentObject_ = flag;
1602 return *this;
1603 }
1604 ContextOptions &toggleNoDefaultCompartmentObject() {
1605 noDefaultCompartmentObject_ = !noDefaultCompartmentObject_;
1606 return *this;
1607 }
1609 bool noScriptRval() const { return noScriptRval_; }
1610 ContextOptions &setNoScriptRval(bool flag) {
1611 noScriptRval_ = flag;
1612 return *this;
1613 }
1614 ContextOptions &toggleNoScriptRval() {
1615 noScriptRval_ = !noScriptRval_;
1616 return *this;
1617 }
1619 bool strictMode() const { return strictMode_; }
1620 ContextOptions &setStrictMode(bool flag) {
1621 strictMode_ = flag;
1622 return *this;
1623 }
1624 ContextOptions &toggleStrictMode() {
1625 strictMode_ = !strictMode_;
1626 return *this;
1627 }
1629 bool cloneSingletons() const { return cloneSingletons_; }
1630 ContextOptions &setCloneSingletons(bool flag) {
1631 cloneSingletons_ = flag;
1632 return *this;
1633 }
1634 ContextOptions &toggleCloneSingletons() {
1635 cloneSingletons_ = !cloneSingletons_;
1636 return *this;
1637 }
1639 private:
1640 bool extraWarnings_ : 1;
1641 bool werror_ : 1;
1642 bool varObjFix_ : 1;
1643 bool privateIsNSISupports_ : 1;
1644 bool dontReportUncaught_ : 1;
1645 bool noDefaultCompartmentObject_ : 1;
1646 bool noScriptRval_ : 1;
1647 bool strictMode_ : 1;
1648 bool cloneSingletons_ : 1;
1649 };
1651 JS_PUBLIC_API(ContextOptions &)
1652 ContextOptionsRef(JSContext *cx);
1654 class JS_PUBLIC_API(AutoSaveContextOptions) {
1655 public:
1656 AutoSaveContextOptions(JSContext *cx)
1657 : cx_(cx),
1658 oldOptions_(ContextOptionsRef(cx_))
1659 {
1660 }
1662 ~AutoSaveContextOptions()
1663 {
1664 ContextOptionsRef(cx_) = oldOptions_;
1665 }
1667 private:
1668 JSContext *cx_;
1669 JS::ContextOptions oldOptions_;
1670 };
1672 } /* namespace JS */
1674 extern JS_PUBLIC_API(const char *)
1675 JS_GetImplementationVersion(void);
1677 extern JS_PUBLIC_API(void)
1678 JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback callback);
1680 extern JS_PUBLIC_API(void)
1681 JS_SetDestroyZoneCallback(JSRuntime *rt, JSZoneCallback callback);
1683 extern JS_PUBLIC_API(void)
1684 JS_SetSweepZoneCallback(JSRuntime *rt, JSZoneCallback callback);
1686 extern JS_PUBLIC_API(void)
1687 JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback);
1689 extern JS_PUBLIC_API(void)
1690 JS_SetWrapObjectCallbacks(JSRuntime *rt, const JSWrapObjectCallbacks *callbacks);
1692 extern JS_PUBLIC_API(void)
1693 JS_SetCompartmentPrivate(JSCompartment *compartment, void *data);
1695 extern JS_PUBLIC_API(void *)
1696 JS_GetCompartmentPrivate(JSCompartment *compartment);
1698 extern JS_PUBLIC_API(void)
1699 JS_SetZoneUserData(JS::Zone *zone, void *data);
1701 extern JS_PUBLIC_API(void *)
1702 JS_GetZoneUserData(JS::Zone *zone);
1704 extern JS_PUBLIC_API(bool)
1705 JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
1707 extern JS_PUBLIC_API(bool)
1708 JS_WrapValue(JSContext *cx, JS::MutableHandleValue vp);
1710 extern JS_PUBLIC_API(bool)
1711 JS_WrapId(JSContext *cx, JS::MutableHandleId idp);
1713 extern JS_PUBLIC_API(JSObject *)
1714 JS_TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject target);
1716 extern JS_PUBLIC_API(bool)
1717 JS_RefreshCrossCompartmentWrappers(JSContext *cx, JS::Handle<JSObject*> obj);
1719 /*
1720 * At any time, a JSContext has a current (possibly-nullptr) compartment.
1721 * Compartments are described in:
1722 *
1723 * developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
1724 *
1725 * The current compartment of a context may be changed. The preferred way to do
1726 * this is with JSAutoCompartment:
1727 *
1728 * void foo(JSContext *cx, JSObject *obj) {
1729 * // in some compartment 'c'
1730 * {
1731 * JSAutoCompartment ac(cx, obj); // constructor enters
1732 * // in the compartment of 'obj'
1733 * } // destructor leaves
1734 * // back in compartment 'c'
1735 * }
1736 *
1737 * For more complicated uses that don't neatly fit in a C++ stack frame, the
1738 * compartment can entered and left using separate function calls:
1739 *
1740 * void foo(JSContext *cx, JSObject *obj) {
1741 * // in 'oldCompartment'
1742 * JSCompartment *oldCompartment = JS_EnterCompartment(cx, obj);
1743 * // in the compartment of 'obj'
1744 * JS_LeaveCompartment(cx, oldCompartment);
1745 * // back in 'oldCompartment'
1746 * }
1747 *
1748 * Note: these calls must still execute in a LIFO manner w.r.t all other
1749 * enter/leave calls on the context. Furthermore, only the return value of a
1750 * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
1751 * the corresponding JS_LeaveCompartment call.
1752 */
1754 class JS_PUBLIC_API(JSAutoCompartment)
1755 {
1756 JSContext *cx_;
1757 JSCompartment *oldCompartment_;
1758 public:
1759 JSAutoCompartment(JSContext *cx, JSObject *target);
1760 JSAutoCompartment(JSContext *cx, JSScript *target);
1761 ~JSAutoCompartment();
1762 };
1764 class JS_PUBLIC_API(JSAutoNullCompartment)
1765 {
1766 JSContext *cx_;
1767 JSCompartment *oldCompartment_;
1768 public:
1769 JSAutoNullCompartment(JSContext *cx);
1770 ~JSAutoNullCompartment();
1771 };
1773 /* NB: This API is infallible; a nullptr return value does not indicate error. */
1774 extern JS_PUBLIC_API(JSCompartment *)
1775 JS_EnterCompartment(JSContext *cx, JSObject *target);
1777 extern JS_PUBLIC_API(void)
1778 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment);
1780 typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);
1782 /*
1783 * This function calls |compartmentCallback| on every compartment. Beware that
1784 * there is no guarantee that the compartment will survive after the callback
1785 * returns.
1786 */
1787 extern JS_PUBLIC_API(void)
1788 JS_IterateCompartments(JSRuntime *rt, void *data,
1789 JSIterateCompartmentCallback compartmentCallback);
1791 /*
1792 * Initialize standard JS class constructors, prototypes, and any top-level
1793 * functions and constants associated with the standard classes (e.g. isNaN
1794 * for Number).
1795 *
1796 * NB: This sets cx's global object to obj if it was null.
1797 */
1798 extern JS_PUBLIC_API(bool)
1799 JS_InitStandardClasses(JSContext *cx, JS::Handle<JSObject*> obj);
1801 /*
1802 * Resolve id, which must contain either a string or an int, to a standard
1803 * class name in obj if possible, defining the class's constructor and/or
1804 * prototype and storing true in *resolved. If id does not name a standard
1805 * class or a top-level property induced by initializing a standard class,
1806 * store false in *resolved and just return true. Return false on error,
1807 * as usual for bool result-typed API entry points.
1808 *
1809 * This API can be called directly from a global object class's resolve op,
1810 * to define standard classes lazily. The class's enumerate op should call
1811 * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in
1812 * loops any classes not yet resolved lazily.
1813 */
1814 extern JS_PUBLIC_API(bool)
1815 JS_ResolveStandardClass(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *resolved);
1817 extern JS_PUBLIC_API(bool)
1818 JS_EnumerateStandardClasses(JSContext *cx, JS::HandleObject obj);
1820 extern JS_PUBLIC_API(bool)
1821 JS_GetClassObject(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1823 extern JS_PUBLIC_API(bool)
1824 JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1826 namespace JS {
1828 /*
1829 * Determine if the given object is an instance or prototype for a standard
1830 * class. If so, return the associated JSProtoKey. If not, return JSProto_Null.
1831 */
1833 extern JS_PUBLIC_API(JSProtoKey)
1834 IdentifyStandardInstance(JSObject *obj);
1836 extern JS_PUBLIC_API(JSProtoKey)
1837 IdentifyStandardPrototype(JSObject *obj);
1839 extern JS_PUBLIC_API(JSProtoKey)
1840 IdentifyStandardInstanceOrPrototype(JSObject *obj);
1842 } /* namespace JS */
1844 extern JS_PUBLIC_API(JSProtoKey)
1845 JS_IdToProtoKey(JSContext *cx, JS::HandleId id);
1847 /*
1848 * Returns the original value of |Function.prototype| from the global object in
1849 * which |forObj| was created.
1850 */
1851 extern JS_PUBLIC_API(JSObject *)
1852 JS_GetFunctionPrototype(JSContext *cx, JS::HandleObject forObj);
1854 /*
1855 * Returns the original value of |Object.prototype| from the global object in
1856 * which |forObj| was created.
1857 */
1858 extern JS_PUBLIC_API(JSObject *)
1859 JS_GetObjectPrototype(JSContext *cx, JS::HandleObject forObj);
1861 /*
1862 * Returns the original value of |Array.prototype| from the global object in
1863 * which |forObj| was created.
1864 */
1865 extern JS_PUBLIC_API(JSObject *)
1866 JS_GetArrayPrototype(JSContext *cx, JS::HandleObject forObj);
1868 extern JS_PUBLIC_API(JSObject *)
1869 JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
1871 extern JS_PUBLIC_API(bool)
1872 JS_IsGlobalObject(JSObject *obj);
1874 /*
1875 * May return nullptr, if |c| never had a global (e.g. the atoms compartment),
1876 * or if |c|'s global has been collected.
1877 */
1878 extern JS_PUBLIC_API(JSObject *)
1879 JS_GetGlobalForCompartmentOrNull(JSContext *cx, JSCompartment *c);
1881 namespace JS {
1883 extern JS_PUBLIC_API(JSObject *)
1884 CurrentGlobalOrNull(JSContext *cx);
1886 }
1888 /*
1889 * Initialize the 'Reflect' object on a global object.
1890 */
1891 extern JS_PUBLIC_API(JSObject *)
1892 JS_InitReflect(JSContext *cx, JS::HandleObject global);
1894 #ifdef JS_HAS_CTYPES
1895 /*
1896 * Initialize the 'ctypes' object on a global variable 'obj'. The 'ctypes'
1897 * object will be sealed.
1898 */
1899 extern JS_PUBLIC_API(bool)
1900 JS_InitCTypesClass(JSContext *cx, JS::HandleObject global);
1902 /*
1903 * Convert a unicode string 'source' of length 'slen' to the platform native
1904 * charset, returning a null-terminated string allocated with JS_malloc. On
1905 * failure, this function should report an error.
1906 */
1907 typedef char *
1908 (* JSCTypesUnicodeToNativeFun)(JSContext *cx, const jschar *source, size_t slen);
1910 /*
1911 * Set of function pointers that ctypes can use for various internal functions.
1912 * See JS_SetCTypesCallbacks below. Providing nullptr for a function is safe,
1913 * and will result in the applicable ctypes functionality not being available.
1914 */
1915 struct JSCTypesCallbacks {
1916 JSCTypesUnicodeToNativeFun unicodeToNative;
1917 };
1919 typedef struct JSCTypesCallbacks JSCTypesCallbacks;
1921 /*
1922 * Set the callbacks on the provided 'ctypesObj' object. 'callbacks' should be a
1923 * pointer to static data that exists for the lifetime of 'ctypesObj', but it
1924 * may safely be altered after calling this function and without having
1925 * to call this function again.
1926 */
1927 extern JS_PUBLIC_API(void)
1928 JS_SetCTypesCallbacks(JSObject *ctypesObj, JSCTypesCallbacks *callbacks);
1929 #endif
1931 typedef bool
1932 (* JSEnumerateDiagnosticMemoryCallback)(void *ptr, size_t length);
1934 /*
1935 * Enumerate memory regions that contain diagnostic information
1936 * intended to be included in crash report minidumps.
1937 */
1938 extern JS_PUBLIC_API(void)
1939 JS_EnumerateDiagnosticMemoryRegions(JSEnumerateDiagnosticMemoryCallback callback);
1941 extern JS_PUBLIC_API(void *)
1942 JS_malloc(JSContext *cx, size_t nbytes);
1944 extern JS_PUBLIC_API(void *)
1945 JS_realloc(JSContext *cx, void *p, size_t nbytes);
1947 /*
1948 * A wrapper for js_free(p) that may delay js_free(p) invocation as a
1949 * performance optimization.
1950 * cx may be nullptr.
1951 */
1952 extern JS_PUBLIC_API(void)
1953 JS_free(JSContext *cx, void *p);
1955 /*
1956 * A wrapper for js_free(p) that may delay js_free(p) invocation as a
1957 * performance optimization as specified by the given JSFreeOp instance.
1958 */
1959 extern JS_PUBLIC_API(void)
1960 JS_freeop(JSFreeOp *fop, void *p);
1962 extern JS_PUBLIC_API(JSFreeOp *)
1963 JS_GetDefaultFreeOp(JSRuntime *rt);
1965 extern JS_PUBLIC_API(void)
1966 JS_updateMallocCounter(JSContext *cx, size_t nbytes);
1968 extern JS_PUBLIC_API(char *)
1969 JS_strdup(JSContext *cx, const char *s);
1971 /* Duplicate a string. Does not report an error on failure. */
1972 extern JS_PUBLIC_API(char *)
1973 JS_strdup(JSRuntime *rt, const char *s);
1975 namespace JS {
1977 /*
1978 * A GC root is a pointer to a jsval, JSObject * or JSString * that itself
1979 * points into the GC heap. JS_AddValueRoot takes a pointer to a jsval and
1980 * JS_AddGCThingRoot takes a pointer to a JSObject * or JString *.
1981 *
1982 * Note that, since JS_Add*Root stores the address of a variable (of type
1983 * jsval, JSString *, or JSObject *), that variable must live until
1984 * JS_Remove*Root is called to remove that variable. For example, after:
1985 *
1986 * void some_function() {
1987 * jsval v;
1988 * JS_AddNamedValueRoot(cx, &v, "name");
1989 *
1990 * the caller must perform
1991 *
1992 * JS_RemoveValueRoot(cx, &v);
1993 *
1994 * before some_function() returns.
1995 *
1996 * Also, use JS_AddNamed*Root(cx, &structPtr->memberObj, "structPtr->memberObj")
1997 * in preference to JS_Add*Root(cx, &structPtr->memberObj), in order to identify
1998 * roots by their source callsites. This way, you can find the callsite while
1999 * debugging if you should fail to do JS_Remove*Root(cx, &structPtr->memberObj)
2000 * before freeing structPtr's memory.
2001 */
2002 extern JS_PUBLIC_API(bool)
2003 AddValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
2005 extern JS_PUBLIC_API(bool)
2006 AddStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
2008 extern JS_PUBLIC_API(bool)
2009 AddObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
2011 extern JS_PUBLIC_API(bool)
2012 AddNamedValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp, const char *name);
2014 extern JS_PUBLIC_API(bool)
2015 AddNamedValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp, const char *name);
2017 extern JS_PUBLIC_API(bool)
2018 AddNamedStringRoot(JSContext *cx, JS::Heap<JSString *> *rp, const char *name);
2020 extern JS_PUBLIC_API(bool)
2021 AddNamedObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp, const char *name);
2023 extern JS_PUBLIC_API(bool)
2024 AddNamedScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp, const char *name);
2026 extern JS_PUBLIC_API(void)
2027 RemoveValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
2029 extern JS_PUBLIC_API(void)
2030 RemoveStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
2032 extern JS_PUBLIC_API(void)
2033 RemoveObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
2035 extern JS_PUBLIC_API(void)
2036 RemoveScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp);
2038 extern JS_PUBLIC_API(void)
2039 RemoveValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp);
2041 extern JS_PUBLIC_API(void)
2042 RemoveStringRootRT(JSRuntime *rt, JS::Heap<JSString *> *rp);
2044 extern JS_PUBLIC_API(void)
2045 RemoveObjectRootRT(JSRuntime *rt, JS::Heap<JSObject *> *rp);
2047 extern JS_PUBLIC_API(void)
2048 RemoveScriptRootRT(JSRuntime *rt, JS::Heap<JSScript *> *rp);
2050 } /* namespace JS */
2052 /*
2053 * Register externally maintained GC roots.
2054 *
2055 * traceOp: the trace operation. For each root the implementation should call
2056 * JS_CallTracer whenever the root contains a traceable thing.
2057 * data: the data argument to pass to each invocation of traceOp.
2058 */
2059 extern JS_PUBLIC_API(bool)
2060 JS_AddExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
2062 /* Undo a call to JS_AddExtraGCRootsTracer. */
2063 extern JS_PUBLIC_API(void)
2064 JS_RemoveExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
2066 #ifdef JS_DEBUG
2068 /*
2069 * Debug-only method to dump the object graph of heap-allocated things.
2070 *
2071 * fp: file for the dump output.
2072 * start: when non-null, dump only things reachable from start
2073 * thing. Otherwise dump all things reachable from the
2074 * runtime roots.
2075 * startKind: trace kind of start if start is not null. Must be
2076 * JSTRACE_OBJECT when start is null.
2077 * thingToFind: dump only paths in the object graph leading to thingToFind
2078 * when non-null.
2079 * maxDepth: the upper bound on the number of edges to descend from the
2080 * graph roots.
2081 * thingToIgnore: thing to ignore during the graph traversal when non-null.
2082 */
2083 extern JS_PUBLIC_API(bool)
2084 JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind kind,
2085 void *thingToFind, size_t maxDepth, void *thingToIgnore);
2087 #endif
2089 /*
2090 * Garbage collector API.
2091 */
2092 extern JS_PUBLIC_API(void)
2093 JS_GC(JSRuntime *rt);
2095 extern JS_PUBLIC_API(void)
2096 JS_MaybeGC(JSContext *cx);
2098 extern JS_PUBLIC_API(void)
2099 JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb, void *data);
2101 extern JS_PUBLIC_API(void)
2102 JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
2104 extern JS_PUBLIC_API(bool)
2105 JS_IsGCMarkingTracer(JSTracer *trc);
2107 /* For assertions only. */
2108 #ifdef JS_DEBUG
2109 extern JS_PUBLIC_API(bool)
2110 JS_IsMarkingGray(JSTracer *trc);
2111 #endif
2113 /*
2114 * JS_IsAboutToBeFinalized checks if the given object is going to be finalized
2115 * at the end of the current GC. When called outside of the context of a GC,
2116 * this function will return false. Typically this function is used on weak
2117 * references, where the reference should be nulled out or destroyed if the
2118 * given object is about to be finalized.
2119 *
2120 * The argument to JS_IsAboutToBeFinalized is an in-out param: when the
2121 * function returns false, the object being referenced is still alive, but the
2122 * garbage collector might have moved it. In this case, the reference passed
2123 * to JS_IsAboutToBeFinalized will be updated to the object's new location.
2124 * Callers of this method are responsible for updating any state that is
2125 * dependent on the object's address. For example, if the object's address is
2126 * used as a key in a hashtable, then the object must be removed and
2127 * re-inserted with the correct hash.
2128 */
2129 extern JS_PUBLIC_API(bool)
2130 JS_IsAboutToBeFinalized(JS::Heap<JSObject *> *objp);
2132 extern JS_PUBLIC_API(bool)
2133 JS_IsAboutToBeFinalizedUnbarriered(JSObject **objp);
2135 typedef enum JSGCParamKey {
2136 /* Maximum nominal heap before last ditch GC. */
2137 JSGC_MAX_BYTES = 0,
2139 /* Number of JS_malloc bytes before last ditch GC. */
2140 JSGC_MAX_MALLOC_BYTES = 1,
2142 /* Amount of bytes allocated by the GC. */
2143 JSGC_BYTES = 3,
2145 /* Number of times when GC was invoked. */
2146 JSGC_NUMBER = 4,
2148 /* Max size of the code cache in bytes. */
2149 JSGC_MAX_CODE_CACHE_BYTES = 5,
2151 /* Select GC mode. */
2152 JSGC_MODE = 6,
2154 /* Number of cached empty GC chunks. */
2155 JSGC_UNUSED_CHUNKS = 7,
2157 /* Total number of allocated GC chunks. */
2158 JSGC_TOTAL_CHUNKS = 8,
2160 /* Max milliseconds to spend in an incremental GC slice. */
2161 JSGC_SLICE_TIME_BUDGET = 9,
2163 /* Maximum size the GC mark stack can grow to. */
2164 JSGC_MARK_STACK_LIMIT = 10,
2166 /*
2167 * GCs less than this far apart in time will be considered 'high-frequency GCs'.
2168 * See setGCLastBytes in jsgc.cpp.
2169 */
2170 JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
2172 /* Start of dynamic heap growth. */
2173 JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
2175 /* End of dynamic heap growth. */
2176 JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
2178 /* Upper bound of heap growth. */
2179 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
2181 /* Lower bound of heap growth. */
2182 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
2184 /* Heap growth for low frequency GCs. */
2185 JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
2187 /*
2188 * If false, the heap growth factor is fixed at 3. If true, it is determined
2189 * based on whether GCs are high- or low- frequency.
2190 */
2191 JSGC_DYNAMIC_HEAP_GROWTH = 17,
2193 /* If true, high-frequency GCs will use a longer mark slice. */
2194 JSGC_DYNAMIC_MARK_SLICE = 18,
2196 /* Lower limit after which we limit the heap growth. */
2197 JSGC_ALLOCATION_THRESHOLD = 19,
2199 /*
2200 * We decommit memory lazily. If more than this number of megabytes is
2201 * available to be decommitted, then JS_MaybeGC will trigger a shrinking GC
2202 * to decommit it.
2203 */
2204 JSGC_DECOMMIT_THRESHOLD = 20
2205 } JSGCParamKey;
2207 extern JS_PUBLIC_API(void)
2208 JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32_t value);
2210 extern JS_PUBLIC_API(uint32_t)
2211 JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key);
2213 extern JS_PUBLIC_API(void)
2214 JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32_t value);
2216 extern JS_PUBLIC_API(uint32_t)
2217 JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
2219 extern JS_PUBLIC_API(void)
2220 JS_SetGCParametersBasedOnAvailableMemory(JSRuntime *rt, uint32_t availMem);
2222 /*
2223 * Create a new JSString whose chars member refers to external memory, i.e.,
2224 * memory requiring application-specific finalization.
2225 */
2226 extern JS_PUBLIC_API(JSString *)
2227 JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
2228 const JSStringFinalizer *fin);
2230 /*
2231 * Return whether 'str' was created with JS_NewExternalString or
2232 * JS_NewExternalStringWithClosure.
2233 */
2234 extern JS_PUBLIC_API(bool)
2235 JS_IsExternalString(JSString *str);
2237 /*
2238 * Return the 'closure' arg passed to JS_NewExternalStringWithClosure or
2239 * nullptr if the external string was created via JS_NewExternalString.
2240 */
2241 extern JS_PUBLIC_API(const JSStringFinalizer *)
2242 JS_GetExternalStringFinalizer(JSString *str);
2244 /*
2245 * Set the size of the native stack that should not be exceed. To disable
2246 * stack size checking pass 0.
2247 *
2248 * SpiderMonkey allows for a distinction between system code (such as GCs, which
2249 * may incidentally be triggered by script but are not strictly performed on
2250 * behalf of such script), trusted script (as determined by JS_SetTrustedPrincipals),
2251 * and untrusted script. Each kind of code may have a different stack quota,
2252 * allowing embedders to keep higher-priority machinery running in the face of
2253 * scripted stack exhaustion by something else.
2254 *
2255 * The stack quotas for each kind of code should be monotonically descending,
2256 * and may be specified with this function. If 0 is passed for a given kind
2257 * of code, it defaults to the value of the next-highest-priority kind.
2258 */
2259 extern JS_PUBLIC_API(void)
2260 JS_SetNativeStackQuota(JSRuntime *cx, size_t systemCodeStackSize,
2261 size_t trustedScriptStackSize = 0,
2262 size_t untrustedScriptStackSize = 0);
2264 /************************************************************************/
2266 extern JS_PUBLIC_API(int)
2267 JS_IdArrayLength(JSContext *cx, JSIdArray *ida);
2269 extern JS_PUBLIC_API(jsid)
2270 JS_IdArrayGet(JSContext *cx, JSIdArray *ida, int index);
2272 extern JS_PUBLIC_API(void)
2273 JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
2275 namespace JS {
2277 class AutoIdArray : private AutoGCRooter
2278 {
2279 public:
2280 AutoIdArray(JSContext *cx, JSIdArray *ida
2281 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
2282 : AutoGCRooter(cx, IDARRAY), context(cx), idArray(ida)
2283 {
2284 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
2285 }
2286 ~AutoIdArray() {
2287 if (idArray)
2288 JS_DestroyIdArray(context, idArray);
2289 }
2290 bool operator!() {
2291 return !idArray;
2292 }
2293 jsid operator[](size_t i) const {
2294 JS_ASSERT(idArray);
2295 return JS_IdArrayGet(context, idArray, i);
2296 }
2297 size_t length() const {
2298 return JS_IdArrayLength(context, idArray);
2299 }
2301 friend void AutoGCRooter::trace(JSTracer *trc);
2303 JSIdArray *steal() {
2304 JSIdArray *copy = idArray;
2305 idArray = nullptr;
2306 return copy;
2307 }
2309 protected:
2310 inline void trace(JSTracer *trc);
2312 private:
2313 JSContext *context;
2314 JSIdArray *idArray;
2315 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
2317 /* No copy or assignment semantics. */
2318 AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
2319 void operator=(AutoIdArray &ida) MOZ_DELETE;
2320 };
2322 } /* namespace JS */
2324 extern JS_PUBLIC_API(bool)
2325 JS_ValueToId(JSContext *cx, JS::HandleValue v, JS::MutableHandleId idp);
2327 extern JS_PUBLIC_API(bool)
2328 JS_StringToId(JSContext *cx, JS::HandleString s, JS::MutableHandleId idp);
2330 extern JS_PUBLIC_API(bool)
2331 JS_IdToValue(JSContext *cx, jsid id, JS::MutableHandle<JS::Value> vp);
2333 /*
2334 * Invoke the [[DefaultValue]] hook (see ES5 8.6.2) with the provided hint on
2335 * the specified object, computing a primitive default value for the object.
2336 * The hint must be JSTYPE_STRING, JSTYPE_NUMBER, or JSTYPE_VOID (no hint). On
2337 * success the resulting value is stored in *vp.
2338 */
2339 extern JS_PUBLIC_API(bool)
2340 JS_DefaultValue(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint,
2341 JS::MutableHandle<JS::Value> vp);
2343 extern JS_PUBLIC_API(bool)
2344 JS_PropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2345 JS::MutableHandleValue vp);
2347 extern JS_PUBLIC_API(bool)
2348 JS_StrictPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
2349 JS::MutableHandleValue vp);
2351 extern JS_PUBLIC_API(bool)
2352 JS_DeletePropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2353 bool *succeeded);
2355 extern JS_PUBLIC_API(bool)
2356 JS_EnumerateStub(JSContext *cx, JS::HandleObject obj);
2358 extern JS_PUBLIC_API(bool)
2359 JS_ResolveStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
2361 extern JS_PUBLIC_API(bool)
2362 JS_ConvertStub(JSContext *cx, JS::HandleObject obj, JSType type,
2363 JS::MutableHandleValue vp);
2365 struct JSConstDoubleSpec {
2366 double dval;
2367 const char *name;
2368 uint8_t flags;
2369 uint8_t spare[3];
2370 };
2372 struct JSJitInfo;
2374 /*
2375 * Wrappers to replace {Strict,}PropertyOp for JSPropertySpecs. This will allow
2376 * us to pass one JSJitInfo per function with the property spec, without
2377 * additional field overhead.
2378 */
2379 typedef struct JSStrictPropertyOpWrapper {
2380 JSStrictPropertyOp op;
2381 const JSJitInfo *info;
2382 } JSStrictPropertyOpWrapper;
2384 typedef struct JSPropertyOpWrapper {
2385 JSPropertyOp op;
2386 const JSJitInfo *info;
2387 } JSPropertyOpWrapper;
2389 /*
2390 * Wrapper to do as above, but for JSNatives for JSFunctionSpecs.
2391 */
2392 typedef struct JSNativeWrapper {
2393 JSNative op;
2394 const JSJitInfo *info;
2395 } JSNativeWrapper;
2397 /*
2398 * Macro static initializers which make it easy to pass no JSJitInfo as part of a
2399 * JSPropertySpec or JSFunctionSpec.
2400 */
2401 #define JSOP_WRAPPER(op) { {op, nullptr} }
2402 #define JSOP_NULLWRAPPER JSOP_WRAPPER(nullptr)
2404 /*
2405 * To define an array element rather than a named property member, cast the
2406 * element's index to (const char *) and initialize name with it, and set the
2407 * JSPROP_INDEX bit in flags.
2408 */
2409 struct JSPropertySpec {
2410 struct SelfHostedWrapper {
2411 void *unused;
2412 const char *funname;
2413 };
2415 const char *name;
2416 uint8_t flags;
2417 union {
2418 JSPropertyOpWrapper propertyOp;
2419 SelfHostedWrapper selfHosted;
2420 } getter;
2421 union {
2422 JSStrictPropertyOpWrapper propertyOp;
2423 SelfHostedWrapper selfHosted;
2424 } setter;
2426 private:
2427 void StaticAsserts() {
2428 JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSPropertyOpWrapper));
2429 JS_STATIC_ASSERT(sizeof(SelfHostedWrapper) == sizeof(JSStrictPropertyOpWrapper));
2430 JS_STATIC_ASSERT(offsetof(SelfHostedWrapper, funname) ==
2431 offsetof(JSPropertyOpWrapper, info));
2432 }
2433 };
2435 namespace JS {
2436 namespace detail {
2438 /* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
2439 inline int CheckIsNative(JSNative native);
2441 /* NEVER DEFINED, DON'T USE. For use by JS_CAST_STRING_TO only. */
2442 template<size_t N>
2443 inline int
2444 CheckIsCharacterLiteral(const char (&arr)[N]);
2446 } // namespace detail
2447 } // namespace JS
2449 #define JS_CAST_NATIVE_TO(v, To) \
2450 (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
2451 reinterpret_cast<To>(v))
2453 #define JS_CAST_STRING_TO(s, To) \
2454 (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
2455 reinterpret_cast<To>(s))
2457 #define JS_CHECK_ACCESSOR_FLAGS(flags) \
2458 (static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))>::Type>(0), \
2459 (flags))
2461 /*
2462 * JSPropertySpec uses JSAPI JSPropertyOp and JSStrictPropertyOp in function
2463 * signatures. These macros encapsulate the definition of JSNative-backed
2464 * JSPropertySpecs, performing type-safe casts on the getter/setter functions
2465 * and adding the necessary property flags to trigger interpretation as
2466 * JSNatives.
2467 */
2468 #define JS_PSG(name, getter, flags) \
2469 {name, \
2470 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
2471 JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
2472 JSOP_NULLWRAPPER}
2473 #define JS_PSGS(name, getter, setter, flags) \
2474 {name, \
2475 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
2476 JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
2477 JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
2478 #define JS_SELF_HOSTED_GET(name, getterName, flags) \
2479 {name, \
2480 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
2481 { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
2482 JSOP_NULLWRAPPER }
2483 #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
2484 {name, \
2485 uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
2486 { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
2487 { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } }
2488 #define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
2490 /*
2491 * To define a native function, set call to a JSNativeWrapper. To define a
2492 * self-hosted function, set selfHostedName to the name of a function
2493 * compiled during JSRuntime::initSelfHosting.
2494 */
2495 struct JSFunctionSpec {
2496 const char *name;
2497 JSNativeWrapper call;
2498 uint16_t nargs;
2499 uint16_t flags;
2500 const char *selfHostedName;
2501 };
2503 /*
2504 * Terminating sentinel initializer to put at the end of a JSFunctionSpec array
2505 * that's passed to JS_DefineFunctions or JS_InitClass.
2506 */
2507 #define JS_FS_END JS_FS(nullptr,nullptr,0,0)
2509 /*
2510 * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays
2511 * homage to the old JSNative/JSFastNative split) simply adds the flag
2512 * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of
2513 * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally
2514 * JS_FNSPEC has slots for all the fields.
2515 */
2516 #define JS_FS(name,call,nargs,flags) \
2517 JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr)
2518 #define JS_FN(name,call,nargs,flags) \
2519 JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr)
2520 #define JS_FNINFO(name,call,info,nargs,flags) \
2521 JS_FNSPEC(name, call, info, nargs, flags, nullptr)
2522 #define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \
2523 JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName)
2524 #define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \
2525 {name, {call, info}, nargs, flags, selfHostedName}
2527 extern JS_PUBLIC_API(JSObject *)
2528 JS_InitClass(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent_proto,
2529 const JSClass *clasp, JSNative constructor, unsigned nargs,
2530 const JSPropertySpec *ps, const JSFunctionSpec *fs,
2531 const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs);
2533 /*
2534 * Set up ctor.prototype = proto and proto.constructor = ctor with the
2535 * right property flags.
2536 */
2537 extern JS_PUBLIC_API(bool)
2538 JS_LinkConstructorAndPrototype(JSContext *cx, JS::Handle<JSObject*> ctor,
2539 JS::Handle<JSObject*> proto);
2541 extern JS_PUBLIC_API(const JSClass *)
2542 JS_GetClass(JSObject *obj);
2544 extern JS_PUBLIC_API(bool)
2545 JS_InstanceOf(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp, JS::CallArgs *args);
2547 extern JS_PUBLIC_API(bool)
2548 JS_HasInstance(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool *bp);
2550 extern JS_PUBLIC_API(void *)
2551 JS_GetPrivate(JSObject *obj);
2553 extern JS_PUBLIC_API(void)
2554 JS_SetPrivate(JSObject *obj, void *data);
2556 extern JS_PUBLIC_API(void *)
2557 JS_GetInstancePrivate(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp,
2558 JS::CallArgs *args);
2560 extern JS_PUBLIC_API(bool)
2561 JS_GetPrototype(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject protop);
2563 extern JS_PUBLIC_API(bool)
2564 JS_SetPrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
2566 extern JS_PUBLIC_API(JSObject *)
2567 JS_GetParent(JSObject *obj);
2569 extern JS_PUBLIC_API(bool)
2570 JS_SetParent(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent);
2572 extern JS_PUBLIC_API(JSObject *)
2573 JS_GetConstructor(JSContext *cx, JS::Handle<JSObject*> proto);
2575 namespace JS {
2577 enum ZoneSpecifier {
2578 FreshZone = 0,
2579 SystemZone = 1
2580 };
2582 class JS_PUBLIC_API(CompartmentOptions)
2583 {
2584 public:
2585 class Override {
2586 public:
2587 Override() : mode_(Default) {}
2589 bool get(bool defaultValue) const {
2590 if (mode_ == Default)
2591 return defaultValue;
2592 return mode_ == ForceTrue;
2593 };
2595 void set(bool overrideValue) {
2596 mode_ = overrideValue ? ForceTrue : ForceFalse;
2597 };
2599 void reset() {
2600 mode_ = Default;
2601 }
2603 private:
2604 enum Mode {
2605 Default,
2606 ForceTrue,
2607 ForceFalse
2608 };
2610 Mode mode_;
2611 };
2613 explicit CompartmentOptions()
2614 : version_(JSVERSION_UNKNOWN)
2615 , invisibleToDebugger_(false)
2616 , mergeable_(false)
2617 , discardSource_(false)
2618 , traceGlobal_(nullptr)
2619 , singletonsAsTemplates_(true)
2620 {
2621 zone_.spec = JS::FreshZone;
2622 }
2624 JSVersion version() const { return version_; }
2625 CompartmentOptions &setVersion(JSVersion aVersion) {
2626 MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
2627 version_ = aVersion;
2628 return *this;
2629 }
2631 // Certain scopes (i.e. XBL compilation scopes) are implementation details
2632 // of the embedding, and references to them should never leak out to script.
2633 // This flag causes the this compartment to skip firing onNewGlobalObject
2634 // and makes addDebuggee a no-op for this global.
2635 bool invisibleToDebugger() const { return invisibleToDebugger_; }
2636 CompartmentOptions &setInvisibleToDebugger(bool flag) {
2637 invisibleToDebugger_ = flag;
2638 return *this;
2639 }
2641 // Compartments used for off-thread compilation have their contents merged
2642 // into a target compartment when the compilation is finished. This is only
2643 // allowed if this flag is set. The invisibleToDebugger flag must also be
2644 // set for such compartments.
2645 bool mergeable() const { return mergeable_; }
2646 CompartmentOptions &setMergeable(bool flag) {
2647 mergeable_ = flag;
2648 return *this;
2649 }
2651 // For certain globals, we know enough about the code that will run in them
2652 // that we can discard script source entirely.
2653 bool discardSource() const { return discardSource_; }
2654 CompartmentOptions &setDiscardSource(bool flag) {
2655 discardSource_ = flag;
2656 return *this;
2657 }
2660 bool cloneSingletons(JSContext *cx) const;
2661 Override &cloneSingletonsOverride() { return cloneSingletonsOverride_; }
2663 void *zonePointer() const {
2664 JS_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
2665 return zone_.pointer;
2666 }
2667 ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
2668 CompartmentOptions &setZone(ZoneSpecifier spec);
2669 CompartmentOptions &setSameZoneAs(JSObject *obj);
2671 void setSingletonsAsValues() {
2672 singletonsAsTemplates_ = false;
2673 }
2674 bool getSingletonsAsTemplates() const {
2675 return singletonsAsTemplates_;
2676 };
2678 CompartmentOptions &setTrace(JSTraceOp op) {
2679 traceGlobal_ = op;
2680 return *this;
2681 }
2682 JSTraceOp getTrace() const {
2683 return traceGlobal_;
2684 }
2686 private:
2687 JSVersion version_;
2688 bool invisibleToDebugger_;
2689 bool mergeable_;
2690 bool discardSource_;
2691 Override cloneSingletonsOverride_;
2692 union {
2693 ZoneSpecifier spec;
2694 void *pointer; // js::Zone* is not exposed in the API.
2695 } zone_;
2696 JSTraceOp traceGlobal_;
2698 // To XDR singletons, we need to ensure that all singletons are all used as
2699 // templates, by making JSOP_OBJECT return a clone of the JSScript
2700 // singleton, instead of returning the value which is baked in the JSScript.
2701 bool singletonsAsTemplates_;
2702 };
2704 JS_PUBLIC_API(CompartmentOptions &)
2705 CompartmentOptionsRef(JSCompartment *compartment);
2707 JS_PUBLIC_API(CompartmentOptions &)
2708 CompartmentOptionsRef(JSObject *obj);
2710 JS_PUBLIC_API(CompartmentOptions &)
2711 CompartmentOptionsRef(JSContext *cx);
2713 // During global creation, we fire notifications to callbacks registered
2714 // via the Debugger API. These callbacks are arbitrary script, and can touch
2715 // the global in arbitrary ways. When that happens, the global should not be
2716 // in a half-baked state. But this creates a problem for consumers that need
2717 // to set slots on the global to put it in a consistent state.
2718 //
2719 // This API provides a way for consumers to set slots atomically (immediately
2720 // after the global is created), before any debugger hooks are fired. It's
2721 // unfortunately on the clunky side, but that's the way the cookie crumbles.
2722 //
2723 // If callers have no additional state on the global to set up, they may pass
2724 // |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to
2725 // fire the hook as its final act before returning. Otherwise, callers should
2726 // pass |DontFireOnNewGlobalHook|, which means that they are responsible for
2727 // invoking JS_FireOnNewGlobalObject upon successfully creating the global. If
2728 // an error occurs and the operation aborts, callers should skip firing the
2729 // hook. But otherwise, callers must take care to fire the hook exactly once
2730 // before compiling any script in the global's scope (we have assertions in
2731 // place to enforce this). This lets us be sure that debugger clients never miss
2732 // breakpoints.
2733 enum OnNewGlobalHookOption {
2734 FireOnNewGlobalHook,
2735 DontFireOnNewGlobalHook
2736 };
2738 } /* namespace JS */
2740 extern JS_PUBLIC_API(JSObject *)
2741 JS_NewGlobalObject(JSContext *cx, const JSClass *clasp, JSPrincipals *principals,
2742 JS::OnNewGlobalHookOption hookOption,
2743 const JS::CompartmentOptions &options = JS::CompartmentOptions());
2744 /*
2745 * Spidermonkey does not have a good way of keeping track of what compartments should be marked on
2746 * their own. We can mark the roots unconditionally, but marking GC things only relevant in live
2747 * compartments is hard. To mitigate this, we create a static trace hook, installed on each global
2748 * object, from which we can be sure the compartment is relevant, and mark it.
2749 *
2750 * It is still possible to specify custom trace hooks for global object classes. They can be
2751 * provided via the CompartmentOptions passed to JS_NewGlobalObject.
2752 */
2753 extern JS_PUBLIC_API(void)
2754 JS_GlobalObjectTraceHook(JSTracer *trc, JSObject *global);
2756 extern JS_PUBLIC_API(void)
2757 JS_FireOnNewGlobalObject(JSContext *cx, JS::HandleObject global);
2759 extern JS_PUBLIC_API(JSObject *)
2760 JS_NewObject(JSContext *cx, const JSClass *clasp, JS::Handle<JSObject*> proto,
2761 JS::Handle<JSObject*> parent);
2763 /* Queries the [[Extensible]] property of the object. */
2764 extern JS_PUBLIC_API(bool)
2765 JS_IsExtensible(JSContext *cx, JS::HandleObject obj, bool *extensible);
2767 extern JS_PUBLIC_API(bool)
2768 JS_IsNative(JSObject *obj);
2770 extern JS_PUBLIC_API(JSRuntime *)
2771 JS_GetObjectRuntime(JSObject *obj);
2773 /*
2774 * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
2775 * proto if proto's actual parameter value is null.
2776 */
2777 extern JS_PUBLIC_API(JSObject *)
2778 JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *clasp, JS::Handle<JSObject*> proto,
2779 JS::Handle<JSObject*> parent);
2781 /*
2782 * Freeze obj, and all objects it refers to, recursively. This will not recurse
2783 * through non-extensible objects, on the assumption that those are already
2784 * deep-frozen.
2785 */
2786 extern JS_PUBLIC_API(bool)
2787 JS_DeepFreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
2789 /*
2790 * Freezes an object; see ES5's Object.freeze(obj) method.
2791 */
2792 extern JS_PUBLIC_API(bool)
2793 JS_FreezeObject(JSContext *cx, JS::Handle<JSObject*> obj);
2795 extern JS_PUBLIC_API(bool)
2796 JS_PreventExtensions(JSContext *cx, JS::HandleObject obj);
2798 extern JS_PUBLIC_API(JSObject *)
2799 JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
2801 extern JS_PUBLIC_API(JSObject *)
2802 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp,
2803 JSObject *proto, unsigned attrs);
2805 extern JS_PUBLIC_API(bool)
2806 JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
2808 extern JS_PUBLIC_API(bool)
2809 JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *ps);
2811 extern JS_PUBLIC_API(bool)
2812 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue value,
2813 unsigned attrs,
2814 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2816 extern JS_PUBLIC_API(bool)
2817 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleObject value,
2818 unsigned attrs,
2819 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2821 extern JS_PUBLIC_API(bool)
2822 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleString value,
2823 unsigned attrs,
2824 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2826 extern JS_PUBLIC_API(bool)
2827 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, int32_t value,
2828 unsigned attrs,
2829 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2831 extern JS_PUBLIC_API(bool)
2832 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, uint32_t value,
2833 unsigned attrs,
2834 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2836 extern JS_PUBLIC_API(bool)
2837 JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, double value,
2838 unsigned attrs,
2839 JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
2841 extern JS_PUBLIC_API(bool)
2842 JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
2843 JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
2845 extern JS_PUBLIC_API(bool)
2846 JS_DefineOwnProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2847 JS::HandleValue descriptor, bool *bp);
2849 extern JS_PUBLIC_API(bool)
2850 JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
2851 bool *foundp);
2853 extern JS_PUBLIC_API(bool)
2854 JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2855 bool *foundp);
2857 extern JS_PUBLIC_API(bool)
2858 JS_HasProperty(JSContext *cx, JS::HandleObject obj, const char *name, bool *foundp);
2860 extern JS_PUBLIC_API(bool)
2861 JS_HasPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
2863 extern JS_PUBLIC_API(bool)
2864 JS_LookupProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
2866 extern JS_PUBLIC_API(bool)
2867 JS_LookupPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2868 JS::MutableHandleValue vp);
2870 struct JSPropertyDescriptor {
2871 JSObject *obj;
2872 unsigned attrs;
2873 JSPropertyOp getter;
2874 JSStrictPropertyOp setter;
2875 JS::Value value;
2877 JSPropertyDescriptor()
2878 : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JSVAL_VOID)
2879 {}
2881 void trace(JSTracer *trc);
2882 };
2884 namespace JS {
2886 template <typename Outer>
2887 class PropertyDescriptorOperations
2888 {
2889 const JSPropertyDescriptor * desc() const { return static_cast<const Outer*>(this)->extract(); }
2891 public:
2892 bool isEnumerable() const { return desc()->attrs & JSPROP_ENUMERATE; }
2893 bool isReadonly() const { return desc()->attrs & JSPROP_READONLY; }
2894 bool isPermanent() const { return desc()->attrs & JSPROP_PERMANENT; }
2895 bool hasNativeAccessors() const { return desc()->attrs & JSPROP_NATIVE_ACCESSORS; }
2896 bool hasGetterObject() const { return desc()->attrs & JSPROP_GETTER; }
2897 bool hasSetterObject() const { return desc()->attrs & JSPROP_SETTER; }
2898 bool hasGetterOrSetterObject() const { return desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER); }
2899 bool isShared() const { return desc()->attrs & JSPROP_SHARED; }
2900 bool isIndex() const { return desc()->attrs & JSPROP_INDEX; }
2901 bool hasAttributes(unsigned attrs) const { return desc()->attrs & attrs; }
2903 JS::HandleObject object() const {
2904 return JS::HandleObject::fromMarkedLocation(&desc()->obj);
2905 }
2906 unsigned attributes() const { return desc()->attrs; }
2907 JSPropertyOp getter() const { return desc()->getter; }
2908 JSStrictPropertyOp setter() const { return desc()->setter; }
2909 JS::HandleObject getterObject() const {
2910 MOZ_ASSERT(hasGetterObject());
2911 return JS::HandleObject::fromMarkedLocation(
2912 reinterpret_cast<JSObject *const *>(&desc()->getter));
2913 }
2914 JS::HandleObject setterObject() const {
2915 MOZ_ASSERT(hasSetterObject());
2916 return JS::HandleObject::fromMarkedLocation(
2917 reinterpret_cast<JSObject *const *>(&desc()->setter));
2918 }
2919 JS::HandleValue value() const {
2920 return JS::HandleValue::fromMarkedLocation(&desc()->value);
2921 }
2922 };
2924 template <typename Outer>
2925 class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
2926 {
2927 JSPropertyDescriptor * desc() { return static_cast<Outer*>(this)->extractMutable(); }
2929 public:
2931 void clear() {
2932 object().set(nullptr);
2933 setAttributes(0);
2934 setGetter(nullptr);
2935 setSetter(nullptr);
2936 value().setUndefined();
2937 }
2939 JS::MutableHandleObject object() {
2940 return JS::MutableHandleObject::fromMarkedLocation(&desc()->obj);
2941 }
2942 unsigned &attributesRef() { return desc()->attrs; }
2943 JSPropertyOp &getter() { return desc()->getter; }
2944 JSStrictPropertyOp &setter() { return desc()->setter; }
2945 JS::MutableHandleValue value() {
2946 return JS::MutableHandleValue::fromMarkedLocation(&desc()->value);
2947 }
2949 void setEnumerable() { desc()->attrs |= JSPROP_ENUMERATE; }
2950 void setAttributes(unsigned attrs) { desc()->attrs = attrs; }
2952 void setGetter(JSPropertyOp op) { desc()->getter = op; }
2953 void setSetter(JSStrictPropertyOp op) { desc()->setter = op; }
2954 void setGetterObject(JSObject *obj) { desc()->getter = reinterpret_cast<JSPropertyOp>(obj); }
2955 void setSetterObject(JSObject *obj) { desc()->setter = reinterpret_cast<JSStrictPropertyOp>(obj); }
2956 };
2958 } /* namespace JS */
2960 namespace js {
2962 template <>
2963 struct GCMethods<JSPropertyDescriptor> {
2964 static JSPropertyDescriptor initial() { return JSPropertyDescriptor(); }
2965 static ThingRootKind kind() { return THING_ROOT_PROPERTY_DESCRIPTOR; }
2966 static bool poisoned(const JSPropertyDescriptor &desc) {
2967 return (desc.obj && JS::IsPoisonedPtr(desc.obj)) ||
2968 (desc.attrs & JSPROP_GETTER && desc.getter && JS::IsPoisonedPtr(desc.getter)) ||
2969 (desc.attrs & JSPROP_SETTER && desc.setter && JS::IsPoisonedPtr(desc.setter)) ||
2970 (desc.value.isGCThing() && JS::IsPoisonedPtr(desc.value.toGCThing()));
2971 }
2972 };
2974 template <>
2975 class RootedBase<JSPropertyDescriptor>
2976 : public JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >
2977 {
2978 friend class JS::PropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
2979 friend class JS::MutablePropertyDescriptorOperations<JS::Rooted<JSPropertyDescriptor> >;
2980 const JSPropertyDescriptor *extract() const {
2981 return static_cast<const JS::Rooted<JSPropertyDescriptor>*>(this)->address();
2982 }
2983 JSPropertyDescriptor *extractMutable() {
2984 return static_cast<JS::Rooted<JSPropertyDescriptor>*>(this)->address();
2985 }
2986 };
2988 template <>
2989 class HandleBase<JSPropertyDescriptor>
2990 : public JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor> >
2991 {
2992 friend class JS::PropertyDescriptorOperations<JS::Handle<JSPropertyDescriptor> >;
2993 const JSPropertyDescriptor *extract() const {
2994 return static_cast<const JS::Handle<JSPropertyDescriptor>*>(this)->address();
2995 }
2996 };
2998 template <>
2999 class MutableHandleBase<JSPropertyDescriptor>
3000 : public JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >
3001 {
3002 friend class JS::PropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >;
3003 friend class JS::MutablePropertyDescriptorOperations<JS::MutableHandle<JSPropertyDescriptor> >;
3004 const JSPropertyDescriptor *extract() const {
3005 return static_cast<const JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
3006 }
3007 JSPropertyDescriptor *extractMutable() {
3008 return static_cast<JS::MutableHandle<JSPropertyDescriptor>*>(this)->address();
3009 }
3010 };
3012 } /* namespace js */
3014 extern JS_PUBLIC_API(bool)
3015 JS_GetOwnPropertyDescriptorById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
3016 JS::MutableHandle<JSPropertyDescriptor> desc);
3018 extern JS_PUBLIC_API(bool)
3019 JS_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
3020 JS::MutableHandle<JSPropertyDescriptor> desc);
3022 /*
3023 * Like JS_GetOwnPropertyDescriptorById but will return a property on
3024 * an object on the prototype chain (returned in desc->obj). If desc->obj is null,
3025 * then this property was not found on the prototype chain.
3026 */
3027 extern JS_PUBLIC_API(bool)
3028 JS_GetPropertyDescriptorById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
3029 JS::MutableHandle<JSPropertyDescriptor> desc);
3031 extern JS_PUBLIC_API(bool)
3032 JS_GetPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
3033 JS::MutableHandle<JSPropertyDescriptor> desc);
3035 extern JS_PUBLIC_API(bool)
3036 JS_GetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
3038 extern JS_PUBLIC_API(bool)
3039 JS_GetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp);
3041 extern JS_PUBLIC_API(bool)
3042 JS_ForwardGetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject onBehalfOf,
3043 JS::MutableHandleValue vp);
3045 extern JS_PUBLIC_API(bool)
3046 JS_SetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue v);
3048 extern JS_PUBLIC_API(bool)
3049 JS_SetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
3051 extern JS_PUBLIC_API(bool)
3052 JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
3054 extern JS_PUBLIC_API(bool)
3055 JS_DeleteProperty2(JSContext *cx, JS::HandleObject obj, const char *name, bool *succeeded);
3057 extern JS_PUBLIC_API(bool)
3058 JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
3060 extern JS_PUBLIC_API(bool)
3061 JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
3063 extern JS_PUBLIC_API(bool)
3064 JS_DefineUCProperty(JSContext *cx, JSObject *obj,
3065 const jschar *name, size_t namelen, jsval value,
3066 JSPropertyOp getter, JSStrictPropertyOp setter,
3067 unsigned attrs);
3069 extern JS_PUBLIC_API(bool)
3070 JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
3071 size_t namelen, bool *foundp);
3073 extern JS_PUBLIC_API(bool)
3074 JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
3075 const jschar *name, size_t namelen,
3076 bool *vp);
3078 extern JS_PUBLIC_API(bool)
3079 JS_LookupUCProperty(JSContext *cx, JS::HandleObject obj,
3080 const jschar *name, size_t namelen,
3081 JS::MutableHandleValue vp);
3083 extern JS_PUBLIC_API(bool)
3084 JS_GetUCProperty(JSContext *cx, JS::HandleObject obj,
3085 const jschar *name, size_t namelen,
3086 JS::MutableHandleValue vp);
3088 extern JS_PUBLIC_API(bool)
3089 JS_SetUCProperty(JSContext *cx, JS::HandleObject obj,
3090 const jschar *name, size_t namelen,
3091 JS::HandleValue v);
3093 extern JS_PUBLIC_API(bool)
3094 JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
3095 bool *succeeded);
3097 extern JS_PUBLIC_API(JSObject *)
3098 JS_NewArrayObject(JSContext *cx, const JS::HandleValueArray& contents);
3100 extern JS_PUBLIC_API(JSObject *)
3101 JS_NewArrayObject(JSContext *cx, size_t length);
3103 extern JS_PUBLIC_API(bool)
3104 JS_IsArrayObject(JSContext *cx, JS::HandleValue value);
3106 extern JS_PUBLIC_API(bool)
3107 JS_IsArrayObject(JSContext *cx, JS::HandleObject obj);
3109 extern JS_PUBLIC_API(bool)
3110 JS_GetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t *lengthp);
3112 extern JS_PUBLIC_API(bool)
3113 JS_SetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t length);
3115 extern JS_PUBLIC_API(bool)
3116 JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,
3117 JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
3119 extern JS_PUBLIC_API(bool)
3120 JS_AlreadyHasOwnElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
3122 extern JS_PUBLIC_API(bool)
3123 JS_HasElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
3125 extern JS_PUBLIC_API(bool)
3126 JS_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
3128 extern JS_PUBLIC_API(bool)
3129 JS_GetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
3131 extern JS_PUBLIC_API(bool)
3132 JS_ForwardGetElementTo(JSContext *cx, JS::HandleObject obj, uint32_t index,
3133 JS::HandleObject onBehalfOf, JS::MutableHandleValue vp);
3135 extern JS_PUBLIC_API(bool)
3136 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
3138 extern JS_PUBLIC_API(bool)
3139 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
3141 extern JS_PUBLIC_API(bool)
3142 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
3144 extern JS_PUBLIC_API(bool)
3145 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, int32_t v);
3147 extern JS_PUBLIC_API(bool)
3148 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, uint32_t v);
3150 extern JS_PUBLIC_API(bool)
3151 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, double v);
3153 extern JS_PUBLIC_API(bool)
3154 JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index);
3156 extern JS_PUBLIC_API(bool)
3157 JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
3159 /*
3160 * Remove all configurable properties from the given (non-global) object and
3161 * assign undefined to all writable data properties.
3162 */
3163 JS_PUBLIC_API(void)
3164 JS_ClearNonGlobalObject(JSContext *cx, JS::HandleObject obj);
3166 /*
3167 * Assign 'undefined' to all of the object's non-reserved slots. Note: this is
3168 * done for all slots, regardless of the associated property descriptor.
3169 */
3170 JS_PUBLIC_API(void)
3171 JS_SetAllNonReservedSlotsToUndefined(JSContext *cx, JSObject *objArg);
3173 /*
3174 * Create a new array buffer with the given contents. On success, the ownership
3175 * is transferred to the new array buffer.
3176 */
3177 extern JS_PUBLIC_API(JSObject *)
3178 JS_NewArrayBufferWithContents(JSContext *cx, size_t nbytes, void *contents);
3180 /*
3181 * Steal the contents of the given array buffer. The array buffer has its
3182 * length set to 0 and its contents array cleared. The caller takes ownership
3183 * of the return value and must free it or transfer ownership via
3184 * JS_NewArrayBufferWithContents when done using it.
3185 */
3186 extern JS_PUBLIC_API(void *)
3187 JS_StealArrayBufferContents(JSContext *cx, JS::HandleObject obj);
3189 /*
3190 * Allocate memory that may be eventually passed to
3191 * JS_NewArrayBufferWithContents. |maybecx| is optional; if a non-nullptr cx is
3192 * given, it will be used for memory accounting and OOM reporting. |nbytes| is
3193 * the number of payload bytes required.
3194 */
3195 extern JS_PUBLIC_API(void *)
3196 JS_AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes);
3198 /*
3199 * Reallocate memory allocated by JS_AllocateArrayBufferContents, growing or
3200 * shrinking it as appropriate. If oldContents is null then this behaves like
3201 * JS_AllocateArrayBufferContents.
3202 */
3203 extern JS_PUBLIC_API(void *)
3204 JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void *oldContents, uint32_t oldNbytes);
3206 /*
3207 * Create a new mapped array buffer with the given memory mapped contents. On success,
3208 * the ownership is transferred to the new mapped array buffer.
3209 */
3210 extern JS_PUBLIC_API(JSObject *)
3211 JS_NewMappedArrayBufferWithContents(JSContext *cx, size_t nbytes, void *contents);
3213 /*
3214 * Create memory mapped array buffer contents.
3215 * Caller must take care of closing fd after calling this function.
3216 */
3217 extern JS_PUBLIC_API(void *)
3218 JS_CreateMappedArrayBufferContents(int fd, size_t offset, size_t length);
3220 /*
3221 * Release the allocated resource of mapped array buffer contents before the
3222 * object is created.
3223 * If a new object has been created by JS_NewMappedArrayBufferWithContents()
3224 * with this content, then JS_NeuterArrayBuffer() should be used instead to
3225 * release the resource used by the object.
3226 */
3227 extern JS_PUBLIC_API(void)
3228 JS_ReleaseMappedArrayBufferContents(void *contents, size_t length);
3230 extern JS_PUBLIC_API(JSIdArray *)
3231 JS_Enumerate(JSContext *cx, JS::HandleObject obj);
3233 /*
3234 * Create an object to iterate over enumerable properties of obj, in arbitrary
3235 * property definition order. NB: This differs from longstanding for..in loop
3236 * order, which uses order of property definition in obj.
3237 */
3238 extern JS_PUBLIC_API(JSObject *)
3239 JS_NewPropertyIterator(JSContext *cx, JS::Handle<JSObject*> obj);
3241 /*
3242 * Return true on success with *idp containing the id of the next enumerable
3243 * property to visit using iterobj, or JSID_IS_VOID if there is no such property
3244 * left to visit. Return false on error.
3245 */
3246 extern JS_PUBLIC_API(bool)
3247 JS_NextProperty(JSContext *cx, JS::Handle<JSObject*> iterobj, jsid *idp);
3249 extern JS_PUBLIC_API(jsval)
3250 JS_GetReservedSlot(JSObject *obj, uint32_t index);
3252 extern JS_PUBLIC_API(void)
3253 JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v);
3255 /************************************************************************/
3257 /*
3258 * Functions and scripts.
3259 */
3260 extern JS_PUBLIC_API(JSFunction *)
3261 JS_NewFunction(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
3262 JS::Handle<JSObject*> parent, const char *name);
3264 /*
3265 * Create the function with the name given by the id. JSID_IS_STRING(id) must
3266 * be true.
3267 */
3268 extern JS_PUBLIC_API(JSFunction *)
3269 JS_NewFunctionById(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
3270 JS::Handle<JSObject*> parent, JS::Handle<jsid> id);
3272 namespace JS {
3274 extern JS_PUBLIC_API(JSFunction *)
3275 GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, JS::Handle<jsid> id,
3276 unsigned nargs);
3278 } /* namespace JS */
3280 extern JS_PUBLIC_API(JSObject *)
3281 JS_GetFunctionObject(JSFunction *fun);
3283 /*
3284 * Return the function's identifier as a JSString, or null if fun is unnamed.
3285 * The returned string lives as long as fun, so you don't need to root a saved
3286 * reference to it if fun is well-connected or rooted, and provided you bound
3287 * the use of the saved reference by fun's lifetime.
3288 */
3289 extern JS_PUBLIC_API(JSString *)
3290 JS_GetFunctionId(JSFunction *fun);
3292 /*
3293 * Return a function's display name. This is the defined name if one was given
3294 * where the function was defined, or it could be an inferred name by the JS
3295 * engine in the case that the function was defined to be anonymous. This can
3296 * still return nullptr if a useful display name could not be inferred. The
3297 * same restrictions on rooting as those in JS_GetFunctionId apply.
3298 */
3299 extern JS_PUBLIC_API(JSString *)
3300 JS_GetFunctionDisplayId(JSFunction *fun);
3302 /*
3303 * Return the arity (length) of fun.
3304 */
3305 extern JS_PUBLIC_API(uint16_t)
3306 JS_GetFunctionArity(JSFunction *fun);
3308 /*
3309 * Infallible predicate to test whether obj is a function object (faster than
3310 * comparing obj's class name to "Function", but equivalent unless someone has
3311 * overwritten the "Function" identifier with a different constructor and then
3312 * created instances using that constructor that might be passed in as obj).
3313 */
3314 extern JS_PUBLIC_API(bool)
3315 JS_ObjectIsFunction(JSContext *cx, JSObject *obj);
3317 extern JS_PUBLIC_API(bool)
3318 JS_ObjectIsCallable(JSContext *cx, JSObject *obj);
3320 extern JS_PUBLIC_API(bool)
3321 JS_IsNativeFunction(JSObject *funobj, JSNative call);
3323 /* Return whether the given function is a valid constructor. */
3324 extern JS_PUBLIC_API(bool)
3325 JS_IsConstructor(JSFunction *fun);
3327 /*
3328 * Bind the given callable to use the given object as "this".
3329 *
3330 * If |callable| is not callable, will throw and return nullptr.
3331 */
3332 extern JS_PUBLIC_API(JSObject*)
3333 JS_BindCallable(JSContext *cx, JS::Handle<JSObject*> callable, JS::Handle<JSObject*> newThis);
3335 extern JS_PUBLIC_API(bool)
3336 JS_DefineFunctions(JSContext *cx, JS::Handle<JSObject*> obj, const JSFunctionSpec *fs);
3338 extern JS_PUBLIC_API(JSFunction *)
3339 JS_DefineFunction(JSContext *cx, JS::Handle<JSObject*> obj, const char *name, JSNative call,
3340 unsigned nargs, unsigned attrs);
3342 extern JS_PUBLIC_API(JSFunction *)
3343 JS_DefineUCFunction(JSContext *cx, JS::Handle<JSObject*> obj,
3344 const jschar *name, size_t namelen, JSNative call,
3345 unsigned nargs, unsigned attrs);
3347 extern JS_PUBLIC_API(JSFunction *)
3348 JS_DefineFunctionById(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JSNative call,
3349 unsigned nargs, unsigned attrs);
3351 /*
3352 * Clone a top-level function into a new scope. This function will dynamically
3353 * fail if funobj was lexically nested inside some other function.
3354 */
3355 extern JS_PUBLIC_API(JSObject *)
3356 JS_CloneFunctionObject(JSContext *cx, JS::Handle<JSObject*> funobj, JS::Handle<JSObject*> parent);
3358 /*
3359 * Given a buffer, return false if the buffer might become a valid
3360 * javascript statement with the addition of more lines. Otherwise return
3361 * true. The intent is to support interactive compilation - accumulate
3362 * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to
3363 * the compiler.
3364 */
3365 extern JS_PUBLIC_API(bool)
3366 JS_BufferIsCompilableUnit(JSContext *cx, JS::Handle<JSObject*> obj, const char *utf8,
3367 size_t length);
3369 extern JS_PUBLIC_API(JSScript *)
3370 JS_CompileScript(JSContext *cx, JS::HandleObject obj,
3371 const char *ascii, size_t length,
3372 const JS::CompileOptions &options);
3374 extern JS_PUBLIC_API(JSScript *)
3375 JS_CompileUCScript(JSContext *cx, JS::HandleObject obj,
3376 const jschar *chars, size_t length,
3377 const JS::CompileOptions &options);
3379 extern JS_PUBLIC_API(JSObject *)
3380 JS_GetGlobalFromScript(JSScript *script);
3382 extern JS_PUBLIC_API(JSFunction *)
3383 JS_CompileFunction(JSContext *cx, JS::HandleObject obj, const char *name,
3384 unsigned nargs, const char *const *argnames,
3385 const char *bytes, size_t length,
3386 const JS::CompileOptions &options);
3388 extern JS_PUBLIC_API(JSFunction *)
3389 JS_CompileUCFunction(JSContext *cx, JS::HandleObject obj, const char *name,
3390 unsigned nargs, const char *const *argnames,
3391 const jschar *chars, size_t length,
3392 const JS::CompileOptions &options);
3394 namespace JS {
3396 /* Options for JavaScript compilation. */
3398 /*
3399 * In the most common use case, a CompileOptions instance is allocated on the
3400 * stack, and holds non-owning references to non-POD option values: strings;
3401 * principals; objects; and so on. The code declaring the instance guarantees
3402 * that such option values will outlive the CompileOptions itself: objects are
3403 * otherwise rooted; principals have had their reference counts bumped; strings
3404 * will not be freed until the CompileOptions goes out of scope. In this
3405 * situation, CompileOptions only refers to things others own, so it can be
3406 * lightweight.
3407 *
3408 * In some cases, however, we need to hold compilation options with a
3409 * non-stack-like lifetime. For example, JS::CompileOffThread needs to save
3410 * compilation options where a worker thread can find them, and then return
3411 * immediately. The worker thread will come along at some later point, and use
3412 * the options.
3413 *
3414 * The compiler itself just needs to be able to access a collection of options;
3415 * it doesn't care who owns them, or what's keeping them alive. It does its own
3416 * addrefs/copies/tracing/etc.
3417 *
3418 * So, we have a class hierarchy that reflects these three use cases:
3419 *
3420 * - ReadOnlyCompileOptions is the common base class. It can be used by code
3421 * that simply needs to access options set elsewhere, like the compiler.
3422 *
3423 * - The usual CompileOptions class must be stack-allocated, and holds
3424 * non-owning references to the filename, element, and so on. It's derived
3425 * from ReadOnlyCompileOptions, so the compiler can use it.
3426 *
3427 * - OwningCompileOptions roots / copies / reference counts of all its values,
3428 * and unroots / frees / releases them when it is destructed. It too is
3429 * derived from ReadOnlyCompileOptions, so the compiler accepts it.
3430 */
3432 /*
3433 * The common base class for the CompileOptions hierarchy.
3434 *
3435 * Use this in code that only needs to access compilation options created
3436 * elsewhere, like the compiler. Don't instantiate this class (the constructor
3437 * is protected anyway); instead, create instances only of the derived classes:
3438 * CompileOptions and OwningCompileOptions.
3439 */
3440 class JS_FRIEND_API(ReadOnlyCompileOptions)
3441 {
3442 friend class CompileOptions;
3444 protected:
3445 JSPrincipals *originPrincipals_;
3446 const char *filename_;
3447 const char *introducerFilename_;
3448 const jschar *sourceMapURL_;
3450 // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure
3451 // is unusable until that's set to something more specific; the derived
3452 // classes' constructors take care of that, in ways appropriate to their
3453 // purpose.
3454 ReadOnlyCompileOptions()
3455 : originPrincipals_(nullptr),
3456 filename_(nullptr),
3457 introducerFilename_(nullptr),
3458 sourceMapURL_(nullptr),
3459 version(JSVERSION_UNKNOWN),
3460 versionSet(false),
3461 utf8(false),
3462 lineno(1),
3463 column(0),
3464 compileAndGo(false),
3465 forEval(false),
3466 defineOnScope(true),
3467 noScriptRval(false),
3468 selfHostingMode(false),
3469 canLazilyParse(true),
3470 strictOption(false),
3471 extraWarningsOption(false),
3472 werrorOption(false),
3473 asmJSOption(false),
3474 forceAsync(false),
3475 installedFile(false),
3476 sourceIsLazy(false),
3477 introductionType(nullptr),
3478 introductionLineno(0),
3479 introductionOffset(0),
3480 hasIntroductionInfo(false)
3481 { }
3483 // Set all POD options (those not requiring reference counts, copies,
3484 // rooting, or other hand-holding) to their values in |rhs|.
3485 void copyPODOptions(const ReadOnlyCompileOptions &rhs);
3487 public:
3488 // Read-only accessors for non-POD options. The proper way to set these
3489 // depends on the derived type.
3490 JSPrincipals *originPrincipals(js::ExclusiveContext *cx) const;
3491 const char *filename() const { return filename_; }
3492 const char *introducerFilename() const { return introducerFilename_; }
3493 const jschar *sourceMapURL() const { return sourceMapURL_; }
3494 virtual JSObject *element() const = 0;
3495 virtual JSString *elementAttributeName() const = 0;
3496 virtual JSScript *introductionScript() const = 0;
3498 // POD options.
3499 JSVersion version;
3500 bool versionSet;
3501 bool utf8;
3502 unsigned lineno;
3503 unsigned column;
3504 bool compileAndGo;
3505 bool forEval;
3506 bool defineOnScope;
3507 bool noScriptRval;
3508 bool selfHostingMode;
3509 bool canLazilyParse;
3510 bool strictOption;
3511 bool extraWarningsOption;
3512 bool werrorOption;
3513 bool asmJSOption;
3514 bool forceAsync;
3515 bool installedFile; // 'true' iff pre-compiling js file in packaged app
3516 bool sourceIsLazy;
3518 // |introductionType| is a statically allocated C string:
3519 // one of "eval", "Function", or "GeneratorFunction".
3520 const char *introductionType;
3521 unsigned introductionLineno;
3522 uint32_t introductionOffset;
3523 bool hasIntroductionInfo;
3525 // Wrap any compilation option values that need it as appropriate for
3526 // use from |compartment|.
3527 virtual bool wrap(JSContext *cx, JSCompartment *compartment) = 0;
3529 private:
3530 static JSObject * const nullObjectPtr;
3531 void operator=(const ReadOnlyCompileOptions &) MOZ_DELETE;
3532 };
3534 /*
3535 * Compilation options, with dynamic lifetime. An instance of this type
3536 * makes a copy of / holds / roots all dynamically allocated resources
3537 * (principals; elements; strings) that it refers to. Its destructor frees
3538 * / drops / unroots them. This is heavier than CompileOptions, below, but
3539 * unlike CompileOptions, it can outlive any given stack frame.
3540 *
3541 * Note that this *roots* any JS values it refers to - they're live
3542 * unconditionally. Thus, instances of this type can't be owned, directly
3543 * or indirectly, by a JavaScript object: if any value that this roots ever
3544 * comes to refer to the object that owns this, then the whole cycle, and
3545 * anything else it entrains, will never be freed.
3546 */
3547 class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions
3548 {
3549 JSRuntime *runtime;
3550 PersistentRootedObject elementRoot;
3551 PersistentRootedString elementAttributeNameRoot;
3552 PersistentRootedScript introductionScriptRoot;
3554 public:
3555 // A minimal constructor, for use with OwningCompileOptions::copy. This
3556 // leaves |this.version| set to JSVERSION_UNKNOWN; the instance
3557 // shouldn't be used until we've set that to something real (as |copy|
3558 // will).
3559 explicit OwningCompileOptions(JSContext *cx);
3560 ~OwningCompileOptions();
3562 JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
3563 JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
3564 JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
3566 // Set this to a copy of |rhs|. Return false on OOM.
3567 bool copy(JSContext *cx, const ReadOnlyCompileOptions &rhs);
3569 /* These setters make copies of their string arguments, and are fallible. */
3570 bool setFile(JSContext *cx, const char *f);
3571 bool setFileAndLine(JSContext *cx, const char *f, unsigned l);
3572 bool setSourceMapURL(JSContext *cx, const jschar *s);
3573 bool setIntroducerFilename(JSContext *cx, const char *s);
3575 /* These setters are infallible, and can be chained. */
3576 OwningCompileOptions &setLine(unsigned l) { lineno = l; return *this; }
3577 OwningCompileOptions &setElement(JSObject *e) {
3578 elementRoot = e;
3579 return *this;
3580 }
3581 OwningCompileOptions &setElementAttributeName(JSString *p) {
3582 elementAttributeNameRoot = p;
3583 return *this;
3584 }
3585 OwningCompileOptions &setIntroductionScript(JSScript *s) {
3586 introductionScriptRoot = s;
3587 return *this;
3588 }
3589 OwningCompileOptions &setOriginPrincipals(JSPrincipals *p) {
3590 if (p) JS_HoldPrincipals(p);
3591 if (originPrincipals_) JS_DropPrincipals(runtime, originPrincipals_);
3592 originPrincipals_ = p;
3593 return *this;
3594 }
3595 OwningCompileOptions &setVersion(JSVersion v) {
3596 version = v;
3597 versionSet = true;
3598 return *this;
3599 }
3600 OwningCompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
3601 OwningCompileOptions &setColumn(unsigned c) { column = c; return *this; }
3602 OwningCompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
3603 OwningCompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
3604 OwningCompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
3605 OwningCompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
3606 OwningCompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
3607 OwningCompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
3608 OwningCompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
3609 OwningCompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
3610 bool setIntroductionInfo(JSContext *cx, const char *introducerFn, const char *intro,
3611 unsigned line, JSScript *script, uint32_t offset)
3612 {
3613 if (!setIntroducerFilename(cx, introducerFn))
3614 return false;
3615 introductionType = intro;
3616 introductionLineno = line;
3617 introductionScriptRoot = script;
3618 introductionOffset = offset;
3619 hasIntroductionInfo = true;
3620 return true;
3621 }
3623 virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
3625 private:
3626 void operator=(const CompileOptions &rhs) MOZ_DELETE;
3627 };
3629 /*
3630 * Compilation options stored on the stack. An instance of this type
3631 * simply holds references to dynamically allocated resources (element;
3632 * filename; source map URL) that are owned by something else. If you
3633 * create an instance of this type, it's up to you to guarantee that
3634 * everything you store in it will outlive it.
3635 */
3636 class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) : public ReadOnlyCompileOptions
3637 {
3638 RootedObject elementRoot;
3639 RootedString elementAttributeNameRoot;
3640 RootedScript introductionScriptRoot;
3642 public:
3643 explicit CompileOptions(JSContext *cx, JSVersion version = JSVERSION_UNKNOWN);
3644 CompileOptions(js::ContextFriendFields *cx, const ReadOnlyCompileOptions &rhs)
3645 : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx),
3646 introductionScriptRoot(cx)
3647 {
3648 copyPODOptions(rhs);
3650 originPrincipals_ = rhs.originPrincipals_;
3651 filename_ = rhs.filename();
3652 sourceMapURL_ = rhs.sourceMapURL();
3653 elementRoot = rhs.element();
3654 elementAttributeNameRoot = rhs.elementAttributeName();
3655 introductionScriptRoot = rhs.introductionScript();
3656 }
3658 JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
3659 JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
3660 JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
3662 CompileOptions &setFile(const char *f) { filename_ = f; return *this; }
3663 CompileOptions &setLine(unsigned l) { lineno = l; return *this; }
3664 CompileOptions &setFileAndLine(const char *f, unsigned l) {
3665 filename_ = f; lineno = l; return *this;
3666 }
3667 CompileOptions &setSourceMapURL(const jschar *s) { sourceMapURL_ = s; return *this; }
3668 CompileOptions &setElement(JSObject *e) { elementRoot = e; return *this; }
3669 CompileOptions &setElementAttributeName(JSString *p) {
3670 elementAttributeNameRoot = p;
3671 return *this;
3672 }
3673 CompileOptions &setIntroductionScript(JSScript *s) {
3674 introductionScriptRoot = s;
3675 return *this;
3676 }
3677 CompileOptions &setOriginPrincipals(JSPrincipals *p) {
3678 originPrincipals_ = p;
3679 return *this;
3680 }
3681 CompileOptions &setVersion(JSVersion v) {
3682 version = v;
3683 versionSet = true;
3684 return *this;
3685 }
3686 CompileOptions &setUTF8(bool u) { utf8 = u; return *this; }
3687 CompileOptions &setColumn(unsigned c) { column = c; return *this; }
3688 CompileOptions &setCompileAndGo(bool cng) { compileAndGo = cng; return *this; }
3689 CompileOptions &setForEval(bool eval) { forEval = eval; return *this; }
3690 CompileOptions &setDefineOnScope(bool define) { defineOnScope = define; return *this; }
3691 CompileOptions &setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; }
3692 CompileOptions &setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; }
3693 CompileOptions &setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; }
3694 CompileOptions &setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; }
3695 CompileOptions &setIntroductionType(const char *t) { introductionType = t; return *this; }
3696 CompileOptions &setIntroductionInfo(const char *introducerFn, const char *intro,
3697 unsigned line, JSScript *script, uint32_t offset)
3698 {
3699 introducerFilename_ = introducerFn;
3700 introductionType = intro;
3701 introductionLineno = line;
3702 introductionScriptRoot = script;
3703 introductionOffset = offset;
3704 hasIntroductionInfo = true;
3705 return *this;
3706 }
3708 virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
3710 private:
3711 void operator=(const CompileOptions &rhs) MOZ_DELETE;
3712 };
3714 /*
3715 * |script| will always be set. On failure, it will be set to nullptr.
3716 */
3717 extern JS_PUBLIC_API(bool)
3718 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3719 SourceBufferHolder &srcBuf, JS::MutableHandleScript script);
3721 extern JS_PUBLIC_API(JSScript *)
3722 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3723 const char *bytes, size_t length);
3725 extern JS_PUBLIC_API(JSScript *)
3726 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3727 const jschar *chars, size_t length);
3729 extern JS_PUBLIC_API(JSScript *)
3730 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, FILE *file);
3732 extern JS_PUBLIC_API(JSScript *)
3733 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename);
3735 extern JS_PUBLIC_API(bool)
3736 CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length);
3738 /*
3739 * Off thread compilation control flow.
3740 *
3741 * After successfully triggering an off thread compile of a script, the
3742 * callback will eventually be invoked with the specified data and a token
3743 * for the compilation. The callback will be invoked while off the main thread,
3744 * so must ensure that its operations are thread safe. Afterwards,
3745 * FinishOffThreadScript must be invoked on the main thread to get the result
3746 * script or nullptr. If maybecx is not specified, the resources will be freed,
3747 * but no script will be returned.
3748 *
3749 * The characters passed in to CompileOffThread must remain live until the
3750 * callback is invoked, and the resulting script will be rooted until the call
3751 * to FinishOffThreadScript.
3752 */
3754 extern JS_PUBLIC_API(bool)
3755 CompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options,
3756 const jschar *chars, size_t length,
3757 OffThreadCompileCallback callback, void *callbackData);
3759 extern JS_PUBLIC_API(JSScript *)
3760 FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token);
3762 extern JS_PUBLIC_API(bool)
3763 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3764 const char *name, unsigned nargs, const char *const *argnames,
3765 SourceBufferHolder &srcBuf, JS::MutableHandleFunction fun);
3767 extern JS_PUBLIC_API(JSFunction *)
3768 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3769 const char *name, unsigned nargs, const char *const *argnames,
3770 const char *bytes, size_t length);
3772 extern JS_PUBLIC_API(JSFunction *)
3773 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3774 const char *name, unsigned nargs, const char *const *argnames,
3775 const jschar *chars, size_t length);
3777 } /* namespace JS */
3779 extern JS_PUBLIC_API(JSString *)
3780 JS_DecompileScript(JSContext *cx, JS::Handle<JSScript*> script, const char *name, unsigned indent);
3782 /*
3783 * API extension: OR this into indent to avoid pretty-printing the decompiled
3784 * source resulting from JS_DecompileFunction{,Body}.
3785 */
3786 #define JS_DONT_PRETTY_PRINT ((unsigned)0x8000)
3788 extern JS_PUBLIC_API(JSString *)
3789 JS_DecompileFunction(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
3791 extern JS_PUBLIC_API(JSString *)
3792 JS_DecompileFunctionBody(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
3794 /*
3795 * NB: JS_ExecuteScript and the JS_Evaluate*Script* quadruplets use the obj
3796 * parameter as the initial scope chain header, the 'this' keyword value, and
3797 * the variables object (ECMA parlance for where 'var' and 'function' bind
3798 * names) of the execution context for script.
3799 *
3800 * Using obj as the variables object is problematic if obj's parent (which is
3801 * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in
3802 * this case, variables created by 'var x = 0', e.g., go in obj, but variables
3803 * created by assignment to an unbound id, 'x = 0', go in the last object on
3804 * the scope chain linked by parent.
3805 *
3806 * ECMA calls that last scoping object the "global object", but note that many
3807 * embeddings have several such objects. ECMA requires that "global code" be
3808 * executed with the variables object equal to this global object. But these
3809 * JS API entry points provide freedom to execute code against a "sub-global",
3810 * i.e., a parented or scoped object, in which case the variables object will
3811 * differ from the last object on the scope chain, resulting in confusing and
3812 * non-ECMA explicit vs. implicit variable creation.
3813 *
3814 * Caveat embedders: unless you already depend on this buggy variables object
3815 * binding behavior, you should call ContextOptionsRef(cx).setVarObjFix(true)
3816 * for each context in the application, if you pass parented objects as the obj
3817 * parameter, or may ever pass such objects in the future.
3818 *
3819 * Why a runtime option? The alternative is to add six or so new API entry
3820 * points with signatures matching the following six, and that doesn't seem
3821 * worth the code bloat cost. Such new entry points would probably have less
3822 * obvious names, too, so would not tend to be used. The JS_SetOption call,
3823 * OTOH, can be more easily hacked into existing code that does not depend on
3824 * the bug; such code can continue to use the familiar JS_EvaluateScript,
3825 * etc., entry points.
3826 */
3827 extern JS_PUBLIC_API(bool)
3828 JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script, JS::MutableHandleValue rval);
3830 extern JS_PUBLIC_API(bool)
3831 JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script);
3833 namespace JS {
3835 /*
3836 * Like the above, but handles a cross-compartment script. If the script is
3837 * cross-compartment, it is cloned into the current compartment before executing.
3838 */
3839 extern JS_PUBLIC_API(bool)
3840 CloneAndExecuteScript(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSScript*> script);
3842 } /* namespace JS */
3844 extern JS_PUBLIC_API(bool)
3845 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
3846 JS::MutableHandleValue rval, JSVersion version);
3848 extern JS_PUBLIC_API(bool)
3849 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
3850 JSVersion version);
3852 extern JS_PUBLIC_API(bool)
3853 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
3854 const char *bytes, unsigned length,
3855 const char *filename, unsigned lineno,
3856 JS::MutableHandleValue rval);
3858 extern JS_PUBLIC_API(bool)
3859 JS_EvaluateScript(JSContext *cx, JS::HandleObject obj,
3860 const char *bytes, unsigned length,
3861 const char *filename, unsigned lineno);
3863 extern JS_PUBLIC_API(bool)
3864 JS_EvaluateUCScript(JSContext *cx, JS::Handle<JSObject*> obj,
3865 const jschar *chars, unsigned length,
3866 const char *filename, unsigned lineno,
3867 JS::MutableHandle<JS::Value> rval);
3869 namespace JS {
3871 extern JS_PUBLIC_API(bool)
3872 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3873 SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
3875 extern JS_PUBLIC_API(bool)
3876 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3877 const jschar *chars, size_t length, JS::MutableHandleValue rval);
3879 extern JS_PUBLIC_API(bool)
3880 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3881 const char *bytes, size_t length, JS::MutableHandleValue rval);
3883 extern JS_PUBLIC_API(bool)
3884 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3885 const char *filename, JS::MutableHandleValue rval);
3887 extern JS_PUBLIC_API(bool)
3888 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3889 SourceBufferHolder &srcBuf);
3891 extern JS_PUBLIC_API(bool)
3892 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3893 const jschar *chars, size_t length);
3895 extern JS_PUBLIC_API(bool)
3896 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3897 const char *bytes, size_t length);
3899 extern JS_PUBLIC_API(bool)
3900 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3901 const char *filename);
3903 } /* namespace JS */
3905 extern JS_PUBLIC_API(bool)
3906 JS_CallFunction(JSContext *cx, JS::HandleObject obj, JS::HandleFunction fun,
3907 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3909 extern JS_PUBLIC_API(bool)
3910 JS_CallFunctionName(JSContext *cx, JS::HandleObject obj, const char *name,
3911 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3913 extern JS_PUBLIC_API(bool)
3914 JS_CallFunctionValue(JSContext *cx, JS::HandleObject obj, JS::HandleValue fval,
3915 const JS::HandleValueArray& args, JS::MutableHandleValue rval);
3917 namespace JS {
3919 static inline bool
3920 Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleFunction fun,
3921 const JS::HandleValueArray &args, MutableHandleValue rval)
3922 {
3923 return !!JS_CallFunction(cx, thisObj, fun, args, rval);
3924 }
3926 static inline bool
3927 Call(JSContext *cx, JS::HandleObject thisObj, const char *name, const JS::HandleValueArray& args,
3928 MutableHandleValue rval)
3929 {
3930 return !!JS_CallFunctionName(cx, thisObj, name, args, rval);
3931 }
3933 static inline bool
3934 Call(JSContext *cx, JS::HandleObject thisObj, JS::HandleValue fun, const JS::HandleValueArray& args,
3935 MutableHandleValue rval)
3936 {
3937 return !!JS_CallFunctionValue(cx, thisObj, fun, args, rval);
3938 }
3940 extern JS_PUBLIC_API(bool)
3941 Call(JSContext *cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
3942 MutableHandleValue rval);
3944 static inline bool
3945 Call(JSContext *cx, JS::HandleValue thisv, JS::HandleObject funObj, const JS::HandleValueArray& args,
3946 MutableHandleValue rval)
3947 {
3948 JS_ASSERT(funObj);
3949 JS::RootedValue fun(cx, JS::ObjectValue(*funObj));
3950 return Call(cx, thisv, fun, args, rval);
3951 }
3953 } /* namespace JS */
3955 /*
3956 * These functions allow setting an interrupt callback that will be called
3957 * from the JS thread some time after any thread triggered the callback using
3958 * JS_RequestInterruptCallback(rt).
3959 *
3960 * To schedule the GC and for other activities the engine internally triggers
3961 * interrupt callbacks. The embedding should thus not rely on callbacks being
3962 * triggered through the external API only.
3963 *
3964 * Important note: Additional callbacks can occur inside the callback handler
3965 * if it re-enters the JS engine. The embedding must ensure that the callback
3966 * is disconnected before attempting such re-entry.
3967 */
3968 extern JS_PUBLIC_API(JSInterruptCallback)
3969 JS_SetInterruptCallback(JSRuntime *rt, JSInterruptCallback callback);
3971 extern JS_PUBLIC_API(JSInterruptCallback)
3972 JS_GetInterruptCallback(JSRuntime *rt);
3974 extern JS_PUBLIC_API(void)
3975 JS_RequestInterruptCallback(JSRuntime *rt);
3977 extern JS_PUBLIC_API(bool)
3978 JS_IsRunning(JSContext *cx);
3980 /*
3981 * Saving and restoring frame chains.
3982 *
3983 * These two functions are used to set aside cx's call stack while that stack
3984 * is inactive. After a call to JS_SaveFrameChain, it looks as if there is no
3985 * code running on cx. Before calling JS_RestoreFrameChain, cx's call stack
3986 * must be balanced and all nested calls to JS_SaveFrameChain must have had
3987 * matching JS_RestoreFrameChain calls.
3988 *
3989 * JS_SaveFrameChain deals with cx not having any code running on it.
3990 */
3991 extern JS_PUBLIC_API(bool)
3992 JS_SaveFrameChain(JSContext *cx);
3994 extern JS_PUBLIC_API(void)
3995 JS_RestoreFrameChain(JSContext *cx);
3997 #ifdef MOZ_TRACE_JSCALLS
3998 /*
3999 * The callback is expected to be quick and noninvasive. It should not
4000 * request interrupts, turn on debugging, or produce uncaught JS
4001 * exceptions. The state of the stack and registers in the context
4002 * cannot be relied upon, since this callback may be invoked directly
4003 * from either JIT. The 'entering' field means we are entering a
4004 * function if it is positive, leaving a function if it is zero or
4005 * negative.
4006 */
4007 extern JS_PUBLIC_API(void)
4008 JS_SetFunctionCallback(JSContext *cx, JSFunctionCallback fcb);
4010 extern JS_PUBLIC_API(JSFunctionCallback)
4011 JS_GetFunctionCallback(JSContext *cx);
4012 #endif /* MOZ_TRACE_JSCALLS */
4014 /************************************************************************/
4016 /*
4017 * Strings.
4018 *
4019 * NB: JS_NewUCString takes ownership of bytes on success, avoiding a copy;
4020 * but on error (signified by null return), it leaves chars owned by the
4021 * caller. So the caller must free bytes in the error case, if it has no use
4022 * for them. In contrast, all the JS_New*StringCopy* functions do not take
4023 * ownership of the character memory passed to them -- they copy it.
4024 */
4025 extern JS_PUBLIC_API(JSString *)
4026 JS_NewStringCopyN(JSContext *cx, const char *s, size_t n);
4028 extern JS_PUBLIC_API(JSString *)
4029 JS_NewStringCopyZ(JSContext *cx, const char *s);
4031 extern JS_PUBLIC_API(JSString *)
4032 JS_InternJSString(JSContext *cx, JS::HandleString str);
4034 extern JS_PUBLIC_API(JSString *)
4035 JS_InternStringN(JSContext *cx, const char *s, size_t length);
4037 extern JS_PUBLIC_API(JSString *)
4038 JS_InternString(JSContext *cx, const char *s);
4040 extern JS_PUBLIC_API(JSString *)
4041 JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
4043 extern JS_PUBLIC_API(JSString *)
4044 JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
4046 extern JS_PUBLIC_API(JSString *)
4047 JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
4049 extern JS_PUBLIC_API(JSString *)
4050 JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
4052 extern JS_PUBLIC_API(JSString *)
4053 JS_InternUCString(JSContext *cx, const jschar *s);
4055 extern JS_PUBLIC_API(bool)
4056 JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
4058 extern JS_PUBLIC_API(bool)
4059 JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, bool *match);
4061 extern JS_PUBLIC_API(size_t)
4062 JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote);
4064 extern JS_PUBLIC_API(bool)
4065 JS_FileEscapedString(FILE *fp, JSString *str, char quote);
4067 /*
4068 * Extracting string characters and length.
4069 *
4070 * While getting the length of a string is infallible, getting the chars can
4071 * fail. As indicated by the lack of a JSContext parameter, there are two
4072 * special cases where getting the chars is infallible:
4073 *
4074 * The first case is interned strings, i.e., strings from JS_InternString or
4075 * JSID_TO_STRING(id), using JS_GetInternedStringChars*.
4076 *
4077 * The second case is "flat" strings that have been explicitly prepared in a
4078 * fallible context by JS_FlattenString. To catch errors, a separate opaque
4079 * JSFlatString type is returned by JS_FlattenString and expected by
4080 * JS_GetFlatStringChars. Note, though, that this is purely a syntactic
4081 * distinction: the input and output of JS_FlattenString are the same actual
4082 * GC-thing so only one needs to be rooted. If a JSString is known to be flat,
4083 * JS_ASSERT_STRING_IS_FLAT can be used to make a debug-checked cast. Example:
4084 *
4085 * // in a fallible context
4086 * JSFlatString *fstr = JS_FlattenString(cx, str);
4087 * if (!fstr)
4088 * return false;
4089 * JS_ASSERT(fstr == JS_ASSERT_STRING_IS_FLAT(str));
4090 *
4091 * // in an infallible context, for the same 'str'
4092 * const jschar *chars = JS_GetFlatStringChars(fstr)
4093 * JS_ASSERT(chars);
4094 *
4095 * The CharsZ APIs guarantee that the returned array has a null character at
4096 * chars[length]. This can require additional copying so clients should prefer
4097 * APIs without CharsZ if possible. The infallible functions also return
4098 * null-terminated arrays. (There is no additional cost or non-Z alternative
4099 * for the infallible functions, so 'Z' is left out of the identifier.)
4100 */
4102 extern JS_PUBLIC_API(size_t)
4103 JS_GetStringLength(JSString *str);
4105 extern JS_PUBLIC_API(const jschar *)
4106 JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
4108 extern JS_PUBLIC_API(const jschar *)
4109 JS_GetInternedStringChars(JSString *str);
4111 extern JS_PUBLIC_API(const jschar *)
4112 JS_GetInternedStringCharsAndLength(JSString *str, size_t *length);
4114 extern JS_PUBLIC_API(const jschar *)
4115 JS_GetStringCharsZ(JSContext *cx, JSString *str);
4117 extern JS_PUBLIC_API(const jschar *)
4118 JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length);
4120 extern JS_PUBLIC_API(JSFlatString *)
4121 JS_FlattenString(JSContext *cx, JSString *str);
4123 extern JS_PUBLIC_API(const jschar *)
4124 JS_GetFlatStringChars(JSFlatString *str);
4126 static MOZ_ALWAYS_INLINE JSFlatString *
4127 JSID_TO_FLAT_STRING(jsid id)
4128 {
4129 JS_ASSERT(JSID_IS_STRING(id));
4130 return (JSFlatString *)(JSID_BITS(id));
4131 }
4133 static MOZ_ALWAYS_INLINE JSFlatString *
4134 JS_ASSERT_STRING_IS_FLAT(JSString *str)
4135 {
4136 JS_ASSERT(JS_GetFlatStringChars((JSFlatString *)str));
4137 return (JSFlatString *)str;
4138 }
4140 static MOZ_ALWAYS_INLINE JSString *
4141 JS_FORGET_STRING_FLATNESS(JSFlatString *fstr)
4142 {
4143 return (JSString *)fstr;
4144 }
4146 /*
4147 * Additional APIs that avoid fallibility when given a flat string.
4148 */
4150 extern JS_PUBLIC_API(bool)
4151 JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes);
4153 extern JS_PUBLIC_API(size_t)
4154 JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote);
4156 /*
4157 * Create a dependent string, i.e., a string that owns no character storage,
4158 * but that refers to a slice of another string's chars. Dependent strings
4159 * are mutable by definition, so the thread safety comments above apply.
4160 */
4161 extern JS_PUBLIC_API(JSString *)
4162 JS_NewDependentString(JSContext *cx, JS::HandleString str, size_t start,
4163 size_t length);
4165 /*
4166 * Concatenate two strings, possibly resulting in a rope.
4167 * See above for thread safety comments.
4168 */
4169 extern JS_PUBLIC_API(JSString *)
4170 JS_ConcatStrings(JSContext *cx, JS::HandleString left, JS::HandleString right);
4172 /*
4173 * For JS_DecodeBytes, set *dstlenp to the size of the destination buffer before
4174 * the call; on return, *dstlenp contains the number of jschars actually stored.
4175 * To determine the necessary destination buffer size, make a sizing call that
4176 * passes nullptr for dst.
4177 *
4178 * On errors, the functions report the error. In that case, *dstlenp contains
4179 * the number of characters or bytes transferred so far. If cx is nullptr, no
4180 * error is reported on failure, and the functions simply return false.
4181 *
4182 * NB: This function does not store an additional zero byte or jschar after the
4183 * transcoded string.
4184 */
4185 JS_PUBLIC_API(bool)
4186 JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst,
4187 size_t *dstlenp);
4189 /*
4190 * A variation on JS_EncodeCharacters where a null terminated string is
4191 * returned that you are expected to call JS_free on when done.
4192 */
4193 JS_PUBLIC_API(char *)
4194 JS_EncodeString(JSContext *cx, JSString *str);
4196 /*
4197 * Same behavior as JS_EncodeString(), but encode into UTF-8 string
4198 */
4199 JS_PUBLIC_API(char *)
4200 JS_EncodeStringToUTF8(JSContext *cx, JS::HandleString str);
4202 /*
4203 * Get number of bytes in the string encoding (without accounting for a
4204 * terminating zero bytes. The function returns (size_t) -1 if the string
4205 * can not be encoded into bytes and reports an error using cx accordingly.
4206 */
4207 JS_PUBLIC_API(size_t)
4208 JS_GetStringEncodingLength(JSContext *cx, JSString *str);
4210 /*
4211 * Encode string into a buffer. The function does not stores an additional
4212 * zero byte. The function returns (size_t) -1 if the string can not be
4213 * encoded into bytes with no error reported. Otherwise it returns the number
4214 * of bytes that are necessary to encode the string. If that exceeds the
4215 * length parameter, the string will be cut and only length bytes will be
4216 * written into the buffer.
4217 */
4218 JS_PUBLIC_API(size_t)
4219 JS_EncodeStringToBuffer(JSContext *cx, JSString *str, char *buffer, size_t length);
4221 class JSAutoByteString
4222 {
4223 public:
4224 JSAutoByteString(JSContext *cx, JSString *str
4225 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
4226 : mBytes(JS_EncodeString(cx, str))
4227 {
4228 JS_ASSERT(cx);
4229 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4230 }
4232 JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
4233 : mBytes(nullptr)
4234 {
4235 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4236 }
4238 ~JSAutoByteString() {
4239 js_free(mBytes);
4240 }
4242 /* Take ownership of the given byte array. */
4243 void initBytes(char *bytes) {
4244 JS_ASSERT(!mBytes);
4245 mBytes = bytes;
4246 }
4248 char *encodeLatin1(JSContext *cx, JSString *str) {
4249 JS_ASSERT(!mBytes);
4250 JS_ASSERT(cx);
4251 mBytes = JS_EncodeString(cx, str);
4252 return mBytes;
4253 }
4255 char *encodeLatin1(js::ExclusiveContext *cx, JSString *str);
4257 char *encodeUtf8(JSContext *cx, JS::HandleString str) {
4258 JS_ASSERT(!mBytes);
4259 JS_ASSERT(cx);
4260 mBytes = JS_EncodeStringToUTF8(cx, str);
4261 return mBytes;
4262 }
4264 void clear() {
4265 js_free(mBytes);
4266 mBytes = nullptr;
4267 }
4269 char *ptr() const {
4270 return mBytes;
4271 }
4273 bool operator!() const {
4274 return !mBytes;
4275 }
4277 size_t length() const {
4278 if (!mBytes)
4279 return 0;
4280 return strlen(mBytes);
4281 }
4283 private:
4284 char *mBytes;
4285 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
4287 /* Copy and assignment are not supported. */
4288 JSAutoByteString(const JSAutoByteString &another);
4289 JSAutoByteString &operator=(const JSAutoByteString &another);
4290 };
4292 /************************************************************************/
4293 /*
4294 * JSON functions
4295 */
4296 typedef bool (* JSONWriteCallback)(const jschar *buf, uint32_t len, void *data);
4298 /*
4299 * JSON.stringify as specified by ES5.
4300 */
4301 JS_PUBLIC_API(bool)
4302 JS_Stringify(JSContext *cx, JS::MutableHandleValue value, JS::HandleObject replacer,
4303 JS::HandleValue space, JSONWriteCallback callback, void *data);
4305 /*
4306 * JSON.parse as specified by ES5.
4307 */
4308 JS_PUBLIC_API(bool)
4309 JS_ParseJSON(JSContext *cx, const jschar *chars, uint32_t len, JS::MutableHandleValue vp);
4311 JS_PUBLIC_API(bool)
4312 JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, JS::HandleValue reviver,
4313 JS::MutableHandleValue vp);
4315 /************************************************************************/
4317 /*
4318 * The default locale for the ECMAScript Internationalization API
4319 * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
4320 * Note that the Internationalization API encourages clients to
4321 * specify their own locales.
4322 * The locale string remains owned by the caller.
4323 */
4324 extern JS_PUBLIC_API(bool)
4325 JS_SetDefaultLocale(JSRuntime *rt, const char *locale);
4327 /*
4328 * Returns the default locale for the ECMAScript Internationalization API
4329 * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
4330 * Note that the Internationalization API encourages clients to
4331 * specify their own locales.
4332 */
4333 extern JS_PUBLIC_API(const char*)
4334 JS_GetDefaultLocale(JSRuntime *rt);
4336 /*
4337 * Reset the default locale to OS defaults.
4338 */
4339 extern JS_PUBLIC_API(void)
4340 JS_ResetDefaultLocale(JSRuntime *rt);
4342 /*
4343 * Locale specific string conversion and error message callbacks.
4344 */
4345 struct JSLocaleCallbacks {
4346 JSLocaleToUpperCase localeToUpperCase;
4347 JSLocaleToLowerCase localeToLowerCase;
4348 JSLocaleCompare localeCompare; // not used #if EXPOSE_INTL_API
4349 JSLocaleToUnicode localeToUnicode;
4350 JSErrorCallback localeGetErrorMessage;
4351 };
4353 /*
4354 * Establish locale callbacks. The pointer must persist as long as the
4355 * JSRuntime. Passing nullptr restores the default behaviour.
4356 */
4357 extern JS_PUBLIC_API(void)
4358 JS_SetLocaleCallbacks(JSRuntime *rt, JSLocaleCallbacks *callbacks);
4360 /*
4361 * Return the address of the current locale callbacks struct, which may
4362 * be nullptr.
4363 */
4364 extern JS_PUBLIC_API(JSLocaleCallbacks *)
4365 JS_GetLocaleCallbacks(JSRuntime *rt);
4367 /************************************************************************/
4369 /*
4370 * Error reporting.
4371 */
4373 /*
4374 * Report an exception represented by the sprintf-like conversion of format
4375 * and its arguments. This exception message string is passed to a pre-set
4376 * JSErrorReporter function (set by JS_SetErrorReporter).
4377 */
4378 extern JS_PUBLIC_API(void)
4379 JS_ReportError(JSContext *cx, const char *format, ...);
4381 /*
4382 * Use an errorNumber to retrieve the format string, args are char *
4383 */
4384 extern JS_PUBLIC_API(void)
4385 JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
4386 void *userRef, const unsigned errorNumber, ...);
4388 #ifdef va_start
4389 extern JS_PUBLIC_API(void)
4390 JS_ReportErrorNumberVA(JSContext *cx, JSErrorCallback errorCallback,
4391 void *userRef, const unsigned errorNumber, va_list ap);
4392 #endif
4394 /*
4395 * Use an errorNumber to retrieve the format string, args are jschar *
4396 */
4397 extern JS_PUBLIC_API(void)
4398 JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback,
4399 void *userRef, const unsigned errorNumber, ...);
4401 extern JS_PUBLIC_API(void)
4402 JS_ReportErrorNumberUCArray(JSContext *cx, JSErrorCallback errorCallback,
4403 void *userRef, const unsigned errorNumber,
4404 const jschar **args);
4406 /*
4407 * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)).
4408 * Return true if there was no error trying to issue the warning, and if the
4409 * warning was not converted into an error due to the JSOPTION_WERROR option
4410 * being set, false otherwise.
4411 */
4412 extern JS_PUBLIC_API(bool)
4413 JS_ReportWarning(JSContext *cx, const char *format, ...);
4415 extern JS_PUBLIC_API(bool)
4416 JS_ReportErrorFlagsAndNumber(JSContext *cx, unsigned flags,
4417 JSErrorCallback errorCallback, void *userRef,
4418 const unsigned errorNumber, ...);
4420 extern JS_PUBLIC_API(bool)
4421 JS_ReportErrorFlagsAndNumberUC(JSContext *cx, unsigned flags,
4422 JSErrorCallback errorCallback, void *userRef,
4423 const unsigned errorNumber, ...);
4425 /*
4426 * Complain when out of memory.
4427 */
4428 extern JS_PUBLIC_API(void)
4429 JS_ReportOutOfMemory(JSContext *cx);
4431 /*
4432 * Complain when an allocation size overflows the maximum supported limit.
4433 */
4434 extern JS_PUBLIC_API(void)
4435 JS_ReportAllocationOverflow(JSContext *cx);
4437 struct JSErrorReport {
4438 const char *filename; /* source file name, URL, etc., or null */
4439 JSPrincipals *originPrincipals; /* see 'originPrincipals' comment above */
4440 unsigned lineno; /* source line number */
4441 const char *linebuf; /* offending source line without final \n */
4442 const char *tokenptr; /* pointer to error token in linebuf */
4443 const jschar *uclinebuf; /* unicode (original) line buffer */
4444 const jschar *uctokenptr; /* unicode (original) token pointer */
4445 unsigned flags; /* error/warning, etc. */
4446 unsigned errorNumber; /* the error number, e.g. see js.msg */
4447 const jschar *ucmessage; /* the (default) error message */
4448 const jschar **messageArgs; /* arguments for the error message */
4449 int16_t exnType; /* One of the JSExnType constants */
4450 unsigned column; /* zero-based column index in line */
4451 };
4453 /*
4454 * JSErrorReport flag values. These may be freely composed.
4455 */
4456 #define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */
4457 #define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */
4458 #define JSREPORT_EXCEPTION 0x2 /* exception was thrown */
4459 #define JSREPORT_STRICT 0x4 /* error or warning due to strict option */
4461 /*
4462 * This condition is an error in strict mode code, a warning if
4463 * JS_HAS_STRICT_OPTION(cx), and otherwise should not be reported at
4464 * all. We check the strictness of the context's top frame's script;
4465 * where that isn't appropriate, the caller should do the right checks
4466 * itself instead of using this flag.
4467 */
4468 #define JSREPORT_STRICT_MODE_ERROR 0x8
4470 /*
4471 * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception
4472 * has been thrown for this runtime error, and the host should ignore it.
4473 * Exception-aware hosts should also check for JS_IsExceptionPending if
4474 * JS_ExecuteScript returns failure, and signal or propagate the exception, as
4475 * appropriate.
4476 */
4477 #define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0)
4478 #define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0)
4479 #define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0)
4480 #define JSREPORT_IS_STRICT_MODE_ERROR(flags) (((flags) & \
4481 JSREPORT_STRICT_MODE_ERROR) != 0)
4482 extern JS_PUBLIC_API(JSErrorReporter)
4483 JS_GetErrorReporter(JSContext *cx);
4485 extern JS_PUBLIC_API(JSErrorReporter)
4486 JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
4488 namespace JS {
4490 extern JS_PUBLIC_API(bool)
4491 CreateTypeError(JSContext *cx, HandleString stack, HandleString fileName,
4492 uint32_t lineNumber, uint32_t columnNumber, JSErrorReport *report,
4493 HandleString message, MutableHandleValue rval);
4495 /************************************************************************/
4497 /*
4498 * Weak Maps.
4499 */
4501 extern JS_PUBLIC_API(JSObject *)
4502 NewWeakMapObject(JSContext *cx);
4504 extern JS_PUBLIC_API(bool)
4505 IsWeakMapObject(JSObject *obj);
4507 extern JS_PUBLIC_API(bool)
4508 GetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
4509 JS::MutableHandleValue val);
4511 extern JS_PUBLIC_API(bool)
4512 SetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
4513 JS::HandleValue val);
4515 } /* namespace JS */
4517 /*
4518 * Dates.
4519 */
4521 extern JS_PUBLIC_API(JSObject *)
4522 JS_NewDateObject(JSContext *cx, int year, int mon, int mday, int hour, int min, int sec);
4524 extern JS_PUBLIC_API(JSObject *)
4525 JS_NewDateObjectMsec(JSContext *cx, double msec);
4527 /*
4528 * Infallible predicate to test whether obj is a date object.
4529 */
4530 extern JS_PUBLIC_API(bool)
4531 JS_ObjectIsDate(JSContext *cx, JS::HandleObject obj);
4533 /*
4534 * Clears the cache of calculated local time from each Date object.
4535 * Call to propagate a system timezone change.
4536 */
4537 extern JS_PUBLIC_API(void)
4538 JS_ClearDateCaches(JSContext *cx);
4540 /************************************************************************/
4542 /*
4543 * Regular Expressions.
4544 */
4545 #define JSREG_FOLD 0x01 /* fold uppercase to lowercase */
4546 #define JSREG_GLOB 0x02 /* global exec, creates array of matches */
4547 #define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */
4548 #define JSREG_STICKY 0x08 /* only match starting at lastIndex */
4550 extern JS_PUBLIC_API(JSObject *)
4551 JS_NewRegExpObject(JSContext *cx, JS::HandleObject obj, char *bytes, size_t length,
4552 unsigned flags);
4554 extern JS_PUBLIC_API(JSObject *)
4555 JS_NewUCRegExpObject(JSContext *cx, JS::HandleObject obj, jschar *chars, size_t length,
4556 unsigned flags);
4558 extern JS_PUBLIC_API(void)
4559 JS_SetRegExpInput(JSContext *cx, JS::HandleObject obj, JS::HandleString input,
4560 bool multiline);
4562 extern JS_PUBLIC_API(void)
4563 JS_ClearRegExpStatics(JSContext *cx, JS::HandleObject obj);
4565 extern JS_PUBLIC_API(bool)
4566 JS_ExecuteRegExp(JSContext *cx, JS::HandleObject obj, JS::HandleObject reobj,
4567 jschar *chars, size_t length, size_t *indexp, bool test,
4568 JS::MutableHandleValue rval);
4570 /* RegExp interface for clients without a global object. */
4572 extern JS_PUBLIC_API(JSObject *)
4573 JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, unsigned flags);
4575 extern JS_PUBLIC_API(JSObject *)
4576 JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, unsigned flags);
4578 extern JS_PUBLIC_API(bool)
4579 JS_ExecuteRegExpNoStatics(JSContext *cx, JS::HandleObject reobj, jschar *chars, size_t length,
4580 size_t *indexp, bool test, JS::MutableHandleValue rval);
4582 extern JS_PUBLIC_API(bool)
4583 JS_ObjectIsRegExp(JSContext *cx, JS::HandleObject obj);
4585 extern JS_PUBLIC_API(unsigned)
4586 JS_GetRegExpFlags(JSContext *cx, JS::HandleObject obj);
4588 extern JS_PUBLIC_API(JSString *)
4589 JS_GetRegExpSource(JSContext *cx, JS::HandleObject obj);
4591 /************************************************************************/
4593 extern JS_PUBLIC_API(bool)
4594 JS_IsExceptionPending(JSContext *cx);
4596 extern JS_PUBLIC_API(bool)
4597 JS_GetPendingException(JSContext *cx, JS::MutableHandleValue vp);
4599 extern JS_PUBLIC_API(void)
4600 JS_SetPendingException(JSContext *cx, JS::HandleValue v);
4602 extern JS_PUBLIC_API(void)
4603 JS_ClearPendingException(JSContext *cx);
4605 extern JS_PUBLIC_API(bool)
4606 JS_ReportPendingException(JSContext *cx);
4608 namespace JS {
4610 /*
4611 * Save and later restore the current exception state of a given JSContext.
4612 * This is useful for implementing behavior in C++ that's like try/catch
4613 * or try/finally in JS.
4614 *
4615 * Typical usage:
4616 *
4617 * bool ok = JS_EvaluateScript(cx, ...);
4618 * AutoSaveExceptionState savedExc(cx);
4619 * ... cleanup that might re-enter JS ...
4620 * return ok;
4621 */
4622 class JS_PUBLIC_API(AutoSaveExceptionState)
4623 {
4624 private:
4625 JSContext *context;
4626 bool wasThrowing;
4627 RootedValue exceptionValue;
4629 public:
4630 /*
4631 * Take a snapshot of cx's current exception state. Then clear any current
4632 * pending exception in cx.
4633 */
4634 explicit AutoSaveExceptionState(JSContext *cx);
4636 /*
4637 * If neither drop() nor restore() was called, restore the exception
4638 * state only if no exception is currently pending on cx.
4639 */
4640 ~AutoSaveExceptionState();
4642 /*
4643 * Discard any stored exception state.
4644 * If this is called, the destructor is a no-op.
4645 */
4646 void drop() {
4647 wasThrowing = false;
4648 exceptionValue.setUndefined();
4649 }
4651 /*
4652 * Replace cx's exception state with the stored exception state. Then
4653 * discard the stored exception state. If this is called, the
4654 * destructor is a no-op.
4655 */
4656 void restore();
4657 };
4659 } /* namespace JS */
4661 /* Deprecated API. Use AutoSaveExceptionState instead. */
4662 extern JS_PUBLIC_API(JSExceptionState *)
4663 JS_SaveExceptionState(JSContext *cx);
4665 extern JS_PUBLIC_API(void)
4666 JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state);
4668 extern JS_PUBLIC_API(void)
4669 JS_DropExceptionState(JSContext *cx, JSExceptionState *state);
4671 /*
4672 * If the given object is an exception object, the exception will have (or be
4673 * able to lazily create) an error report struct, and this function will return
4674 * the address of that struct. Otherwise, it returns nullptr. The lifetime
4675 * of the error report struct that might be returned is the same as the
4676 * lifetime of the exception object.
4677 */
4678 extern JS_PUBLIC_API(JSErrorReport *)
4679 JS_ErrorFromException(JSContext *cx, JS::HandleObject obj);
4681 /*
4682 * Throws a StopIteration exception on cx.
4683 */
4684 extern JS_PUBLIC_API(bool)
4685 JS_ThrowStopIteration(JSContext *cx);
4687 extern JS_PUBLIC_API(bool)
4688 JS_IsStopIteration(jsval v);
4690 extern JS_PUBLIC_API(intptr_t)
4691 JS_GetCurrentThread();
4693 /*
4694 * A JS runtime always has an "owner thread". The owner thread is set when the
4695 * runtime is created (to the current thread) and practically all entry points
4696 * into the JS engine check that a runtime (or anything contained in the
4697 * runtime: context, compartment, object, etc) is only touched by its owner
4698 * thread. Embeddings may check this invariant outside the JS engine by calling
4699 * JS_AbortIfWrongThread (which will abort if not on the owner thread, even for
4700 * non-debug builds).
4701 */
4703 extern JS_PUBLIC_API(void)
4704 JS_AbortIfWrongThread(JSRuntime *rt);
4706 /************************************************************************/
4708 /*
4709 * A constructor can request that the JS engine create a default new 'this'
4710 * object of the given class, using the callee to determine parentage and
4711 * [[Prototype]].
4712 */
4713 extern JS_PUBLIC_API(JSObject *)
4714 JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const JS::CallArgs& args);
4716 /************************************************************************/
4718 #ifdef JS_GC_ZEAL
4719 #define JS_DEFAULT_ZEAL_FREQ 100
4721 extern JS_PUBLIC_API(void)
4722 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
4724 extern JS_PUBLIC_API(void)
4725 JS_ScheduleGC(JSContext *cx, uint32_t count);
4726 #endif
4728 extern JS_PUBLIC_API(void)
4729 JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled);
4731 extern JS_PUBLIC_API(void)
4732 JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled);
4734 #define JIT_COMPILER_OPTIONS(Register) \
4735 Register(BASELINE_USECOUNT_TRIGGER, "baseline.usecount.trigger") \
4736 Register(ION_USECOUNT_TRIGGER, "ion.usecount.trigger") \
4737 Register(ION_ENABLE, "ion.enable") \
4738 Register(BASELINE_ENABLE, "baseline.enable") \
4739 Register(PARALLEL_COMPILATION_ENABLE, "parallel-compilation.enable")
4741 typedef enum JSJitCompilerOption {
4742 #define JIT_COMPILER_DECLARE(key, str) \
4743 JSJITCOMPILER_ ## key,
4745 JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
4746 #undef JIT_COMPILER_DECLARE
4748 JSJITCOMPILER_NOT_AN_OPTION
4749 } JSJitCompilerOption;
4751 extern JS_PUBLIC_API(void)
4752 JS_SetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt, uint32_t value);
4753 extern JS_PUBLIC_API(int)
4754 JS_GetGlobalJitCompilerOption(JSRuntime *rt, JSJitCompilerOption opt);
4756 /*
4757 * Convert a uint32_t index into a jsid.
4758 */
4759 extern JS_PUBLIC_API(bool)
4760 JS_IndexToId(JSContext *cx, uint32_t index, JS::MutableHandleId);
4762 /*
4763 * Convert chars into a jsid.
4764 *
4765 * |chars| may not be an index.
4766 */
4767 extern JS_PUBLIC_API(bool)
4768 JS_CharsToId(JSContext* cx, JS::TwoByteChars chars, JS::MutableHandleId);
4770 /*
4771 * Test if the given string is a valid ECMAScript identifier
4772 */
4773 extern JS_PUBLIC_API(bool)
4774 JS_IsIdentifier(JSContext *cx, JS::HandleString str, bool *isIdentifier);
4776 namespace JS {
4778 /*
4779 * AutoFilename encapsulates a pointer to a C-string and keeps the C-string
4780 * alive for as long as the associated AutoFilename object is alive.
4781 */
4782 class MOZ_STACK_CLASS JS_PUBLIC_API(AutoFilename)
4783 {
4784 void *scriptSource_;
4786 AutoFilename(const AutoFilename &) MOZ_DELETE;
4787 void operator=(const AutoFilename &) MOZ_DELETE;
4789 public:
4790 AutoFilename() : scriptSource_(nullptr) {}
4791 ~AutoFilename() { reset(nullptr); }
4793 const char *get() const;
4795 void reset(void *newScriptSource);
4796 };
4798 /*
4799 * Return the current filename and line number of the most currently running
4800 * frame. Returns true if a scripted frame was found, false otherwise.
4801 *
4802 * If a the embedding has hidden the scripted caller for the topmost activation
4803 * record, this will also return false.
4804 */
4805 extern JS_PUBLIC_API(bool)
4806 DescribeScriptedCaller(JSContext *cx, AutoFilename *filename = nullptr,
4807 unsigned *lineno = nullptr);
4809 extern JS_PUBLIC_API(JSObject *)
4810 GetScriptedCallerGlobal(JSContext *cx);
4812 /*
4813 * Informs the JS engine that the scripted caller should be hidden. This can be
4814 * used by the embedding to maintain an override of the scripted caller in its
4815 * calculations, by hiding the scripted caller in the JS engine and pushing data
4816 * onto a separate stack, which it inspects when DescribeScriptedCaller returns
4817 * null.
4818 *
4819 * We maintain a counter on each activation record. Add() increments the counter
4820 * of the topmost activation, and Remove() decrements it. The count may never
4821 * drop below zero, and must always be exactly zero when the activation is
4822 * popped from the stack.
4823 */
4824 extern JS_PUBLIC_API(void)
4825 HideScriptedCaller(JSContext *cx);
4827 extern JS_PUBLIC_API(void)
4828 UnhideScriptedCaller(JSContext *cx);
4830 class AutoHideScriptedCaller
4831 {
4832 public:
4833 AutoHideScriptedCaller(JSContext *cx
4834 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
4835 : mContext(cx)
4836 {
4837 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4838 HideScriptedCaller(mContext);
4839 }
4840 ~AutoHideScriptedCaller() {
4841 UnhideScriptedCaller(mContext);
4842 }
4844 protected:
4845 JSContext *mContext;
4846 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
4847 };
4849 } /* namespace JS */
4851 /*
4852 * Encode/Decode interpreted scripts and functions to/from memory.
4853 */
4855 extern JS_PUBLIC_API(void *)
4856 JS_EncodeScript(JSContext *cx, JS::HandleScript script, uint32_t *lengthp);
4858 extern JS_PUBLIC_API(void *)
4859 JS_EncodeInterpretedFunction(JSContext *cx, JS::HandleObject funobj, uint32_t *lengthp);
4861 extern JS_PUBLIC_API(JSScript *)
4862 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length, JSPrincipals *originPrincipals);
4864 extern JS_PUBLIC_API(JSObject *)
4865 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
4866 JSPrincipals *originPrincipals);
4868 namespace JS {
4870 /*
4871 * This callback represents a request by the JS engine to open for reading the
4872 * existing cache entry for the given global and char range that may contain a
4873 * module. If a cache entry exists, the callback shall return 'true' and return
4874 * the size, base address and an opaque file handle as outparams. If the
4875 * callback returns 'true', the JS engine guarantees a call to
4876 * CloseAsmJSCacheEntryForReadOp, passing the same base address, size and
4877 * handle.
4878 */
4879 typedef bool
4880 (* OpenAsmJSCacheEntryForReadOp)(HandleObject global, const jschar *begin, const jschar *limit,
4881 size_t *size, const uint8_t **memory, intptr_t *handle);
4882 typedef void
4883 (* CloseAsmJSCacheEntryForReadOp)(HandleObject global, size_t size, const uint8_t *memory,
4884 intptr_t handle);
4886 /*
4887 * This callback represents a request by the JS engine to open for writing a
4888 * cache entry of the given size for the given global and char range containing
4889 * the just-compiled module. If cache entry space is available, the callback
4890 * shall return 'true' and return the base address and an opaque file handle as
4891 * outparams. If the callback returns 'true', the JS engine guarantees a call
4892 * to CloseAsmJSCacheEntryForWriteOp passing the same base address, size and
4893 * handle.
4894 *
4895 * If 'installed' is true, then the cache entry is associated with a permanently
4896 * installed JS file (e.g., in a packaged webapp). This information allows the
4897 * embedding to store the cache entry in a installed location associated with
4898 * the principal of 'global' where it will not be evicted until the associated
4899 * installed JS file is removed.
4900 */
4901 typedef bool
4902 (* OpenAsmJSCacheEntryForWriteOp)(HandleObject global, bool installed,
4903 const jschar *begin, const jschar *end,
4904 size_t size, uint8_t **memory, intptr_t *handle);
4905 typedef void
4906 (* CloseAsmJSCacheEntryForWriteOp)(HandleObject global, size_t size, uint8_t *memory,
4907 intptr_t handle);
4909 typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
4911 // Return the buildId (represented as a sequence of characters) associated with
4912 // the currently-executing build. If the JS engine is embedded such that a
4913 // single cache entry can be observed by different compiled versions of the JS
4914 // engine, it is critical that the buildId shall change for each new build of
4915 // the JS engine.
4917 typedef bool
4918 (* BuildIdOp)(BuildIdCharVector *buildId);
4920 struct AsmJSCacheOps
4921 {
4922 OpenAsmJSCacheEntryForReadOp openEntryForRead;
4923 CloseAsmJSCacheEntryForReadOp closeEntryForRead;
4924 OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
4925 CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
4926 BuildIdOp buildId;
4927 };
4929 extern JS_PUBLIC_API(void)
4930 SetAsmJSCacheOps(JSRuntime *rt, const AsmJSCacheOps *callbacks);
4932 /*
4933 * Convenience class for imitating a JS level for-of loop. Typical usage:
4934 *
4935 * ForOfIterator it(cx);
4936 * if (!it.init(iterable))
4937 * return false;
4938 * RootedValue val(cx);
4939 * while (true) {
4940 * bool done;
4941 * if (!it.next(&val, &done))
4942 * return false;
4943 * if (done)
4944 * break;
4945 * if (!DoStuff(cx, val))
4946 * return false;
4947 * }
4948 */
4949 class MOZ_STACK_CLASS JS_PUBLIC_API(ForOfIterator) {
4950 protected:
4951 JSContext *cx_;
4952 /*
4953 * Use the ForOfPIC on the global object (see vm/GlobalObject.h) to try
4954 * to optimize iteration across arrays.
4955 *
4956 * Case 1: Regular Iteration
4957 * iterator - pointer to the iterator object.
4958 * index - fixed to NOT_ARRAY (== UINT32_MAX)
4959 *
4960 * Case 2: Optimized Array Iteration
4961 * iterator - pointer to the array object.
4962 * index - current position in array.
4963 *
4964 * The cases are distinguished by whether or not |index| is equal to NOT_ARRAY.
4965 */
4966 JS::RootedObject iterator;
4967 uint32_t index;
4969 static const uint32_t NOT_ARRAY = UINT32_MAX;
4971 ForOfIterator(const ForOfIterator &) MOZ_DELETE;
4972 ForOfIterator &operator=(const ForOfIterator &) MOZ_DELETE;
4974 public:
4975 ForOfIterator(JSContext *cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
4977 enum NonIterableBehavior {
4978 ThrowOnNonIterable,
4979 AllowNonIterable
4980 };
4982 /*
4983 * Initialize the iterator. If AllowNonIterable is passed then if iterable
4984 * does not have a callable @@iterator init() will just return true instead
4985 * of throwing. Callers should then check valueIsIterable() before
4986 * continuing with the iteration.
4987 */
4988 bool init(JS::HandleValue iterable,
4989 NonIterableBehavior nonIterableBehavior = ThrowOnNonIterable);
4991 /*
4992 * Get the next value from the iterator. If false *done is true
4993 * after this call, do not examine val.
4994 */
4995 bool next(JS::MutableHandleValue val, bool *done);
4997 /*
4998 * If initialized with throwOnNonCallable = false, check whether
4999 * the value is iterable.
5000 */
5001 bool valueIsIterable() const {
5002 return iterator;
5003 }
5005 private:
5006 inline bool nextFromOptimizedArray(MutableHandleValue val, bool *done);
5007 bool materializeArrayIterator();
5008 };
5011 /*
5012 * If a large allocation fails, the JS engine may call the large-allocation-
5013 * failure callback, if set, to allow the embedding to flush caches, possibly
5014 * perform shrinking GCs, etc. to make some room so that the allocation will
5015 * succeed if retried. After the callback returns, the JS engine will try to
5016 * allocate again and may be succesful.
5017 */
5019 typedef void
5020 (* LargeAllocationFailureCallback)();
5022 extern JS_PUBLIC_API(void)
5023 SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc);
5025 /*
5026 * Unlike the error reporter, which is only called if the exception for an OOM
5027 * bubbles up and is not caught, the OutOfMemoryCallback is called immediately
5028 * at the OOM site to allow the embedding to capture the current state of heap
5029 * allocation before anything is freed. If the large-allocation-failure callback
5030 * is called at all (not all allocation sites call the large-allocation-failure
5031 * callback on failure), it is called before the out-of-memory callback; the
5032 * out-of-memory callback is only called if the allocation still fails after the
5033 * large-allocation-failure callback has returned.
5034 */
5036 typedef void
5037 (* OutOfMemoryCallback)(JSContext *cx);
5039 extern JS_PUBLIC_API(void)
5040 SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb);
5042 } /* namespace JS */
5044 #endif /* jsapi_h */