js/src/jsapi.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:8f0d5d35fb6b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /* JavaScript API. */
8
9 #ifndef jsapi_h
10 #define jsapi_h
11
12 #include "mozilla/FloatingPoint.h"
13 #include "mozilla/MemoryReporting.h"
14 #include "mozilla/RangedPtr.h"
15
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <stdio.h>
20
21 #include "jsalloc.h"
22 #include "jspubtd.h"
23
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"
34
35 /************************************************************************/
36
37 namespace JS {
38
39 class Latin1CharsZ;
40 class TwoByteChars;
41
42 #if defined JS_THREADSAFE && defined JS_DEBUG
43
44 class JS_PUBLIC_API(AutoCheckRequestDepth)
45 {
46 JSContext *cx;
47 public:
48 AutoCheckRequestDepth(JSContext *cx);
49 AutoCheckRequestDepth(js::ContextFriendFields *cx);
50 ~AutoCheckRequestDepth();
51 };
52
53 # define CHECK_REQUEST(cx) \
54 JS::AutoCheckRequestDepth _autoCheckRequestDepth(cx)
55
56 #else
57
58 # define CHECK_REQUEST(cx) \
59 ((void) 0)
60
61 #endif /* JS_THREADSAFE && JS_DEBUG */
62
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 */
76
77 class JS_PUBLIC_API(AutoGCRooter) {
78 public:
79 AutoGCRooter(JSContext *cx, ptrdiff_t tag);
80 AutoGCRooter(js::ContextFriendFields *cx, ptrdiff_t tag);
81
82 ~AutoGCRooter() {
83 JS_ASSERT(this == *stackTop);
84 *stackTop = down;
85 }
86
87 /* Implemented in gc/RootMarking.cpp. */
88 inline void trace(JSTracer *trc);
89 static void traceAll(JSTracer *trc);
90 static void traceAllWrappers(JSTracer *trc);
91
92 protected:
93 AutoGCRooter * const down;
94
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_;
103
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 };
129
130 private:
131 AutoGCRooter ** const stackTop;
132
133 /* No copy or assignment semantics. */
134 AutoGCRooter(AutoGCRooter &ida) MOZ_DELETE;
135 void operator=(AutoGCRooter &ida) MOZ_DELETE;
136 };
137
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];
144
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 }
154
155 unsigned length() const { return length_; }
156 const Value *begin() const { return elements_; }
157 Value *begin() { return elements_; }
158
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 }
167
168 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
169 };
170
171 template<class T>
172 class AutoVectorRooter : protected AutoGCRooter
173 {
174 typedef js::Vector<T, 8> VectorImpl;
175 VectorImpl vector;
176
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 }
184
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 }
191
192 typedef T ElementType;
193 typedef typename VectorImpl::Range Range;
194
195 size_t length() const { return vector.length(); }
196 bool empty() const { return vector.empty(); }
197
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 }
203
204 bool insert(T *p, const T &val) { return vector.insert(p, val); }
205
206 /* For use when space has already been reserved. */
207 void infallibleAppend(const T &v) { vector.infallibleAppend(v); }
208
209 void popBack() { vector.popBack(); }
210 T popCopy() { return vector.popCopy(); }
211
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 }
219
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 }
231
232 void clear() { vector.clear(); }
233
234 bool reserve(size_t newLength) {
235 return vector.reserve(newLength);
236 }
237
238 T &operator[](size_t i) { return vector[i]; }
239 const T &operator[](size_t i) const { return vector[i]; }
240
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 }
247
248 const T *begin() const { return vector.begin(); }
249 T *begin() { return vector.begin(); }
250
251 const T *end() const { return vector.end(); }
252 T *end() { return vector.end(); }
253
254 Range all() { return vector.all(); }
255
256 const T &back() const { return vector.back(); }
257
258 friend void AutoGCRooter::trace(JSTracer *trc);
259
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 }
266
267 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
268 };
269
270 template<class Key, class Value>
271 class AutoHashMapRooter : protected AutoGCRooter
272 {
273 private:
274 typedef js::HashMap<Key, Value> HashMapImpl;
275
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 }
283
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;
290
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 }
306
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 }
311
312 bool add(AddPtr &p, const Key &k) {
313 return map.add(p, k);
314 }
315
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 }
320
321 typedef typename HashMapImpl::Range Range;
322 Range all() const {
323 return map.all();
324 }
325
326 typedef typename HashMapImpl::Enum Enum;
327
328 void clear() {
329 map.clear();
330 }
331
332 void finish() {
333 map.finish();
334 }
335
336 bool empty() const {
337 return map.empty();
338 }
339
340 uint32_t count() const {
341 return map.count();
342 }
343
344 size_t capacity() const {
345 return map.capacity();
346 }
347
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 }
354
355 unsigned generation() const {
356 return map.generation();
357 }
358
359 /************************************************** Shorthand operations */
360
361 bool has(const Lookup &l) const {
362 return map.has(l);
363 }
364
365 template<typename KeyInput, typename ValueInput>
366 bool put(const KeyInput &k, const ValueInput &v) {
367 return map.put(k, v);
368 }
369
370 template<typename KeyInput, typename ValueInput>
371 bool putNew(const KeyInput &k, const ValueInput &v) {
372 return map.putNew(k, v);
373 }
374
375 Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
376 return map.lookupWithDefault(k, defaultValue);
377 }
378
379 void remove(const Lookup &l) {
380 map.remove(l);
381 }
382
383 friend void AutoGCRooter::trace(JSTracer *trc);
384
385 private:
386 AutoHashMapRooter(const AutoHashMapRooter &hmr) MOZ_DELETE;
387 AutoHashMapRooter &operator=(const AutoHashMapRooter &hmr) MOZ_DELETE;
388
389 HashMapImpl map;
390
391 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
392 };
393
394 template<class T>
395 class AutoHashSetRooter : protected AutoGCRooter
396 {
397 private:
398 typedef js::HashSet<T> HashSetImpl;
399
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 }
407
408 typedef typename HashSetImpl::Lookup Lookup;
409 typedef typename HashSetImpl::Ptr Ptr;
410 typedef typename HashSetImpl::AddPtr AddPtr;
411
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 }
427
428 bool add(AddPtr &p, const T &t) {
429 return set.add(p, t);
430 }
431
432 bool relookupOrAdd(AddPtr &p, const Lookup &l, const T &t) {
433 return set.relookupOrAdd(p, l, t);
434 }
435
436 typedef typename HashSetImpl::Range Range;
437 Range all() const {
438 return set.all();
439 }
440
441 typedef typename HashSetImpl::Enum Enum;
442
443 void clear() {
444 set.clear();
445 }
446
447 void finish() {
448 set.finish();
449 }
450
451 bool empty() const {
452 return set.empty();
453 }
454
455 uint32_t count() const {
456 return set.count();
457 }
458
459 size_t capacity() const {
460 return set.capacity();
461 }
462
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 }
469
470 unsigned generation() const {
471 return set.generation();
472 }
473
474 /************************************************** Shorthand operations */
475
476 bool has(const Lookup &l) const {
477 return set.has(l);
478 }
479
480 bool put(const T &t) {
481 return set.put(t);
482 }
483
484 bool putNew(const T &t) {
485 return set.putNew(t);
486 }
487
488 void remove(const Lookup &l) {
489 set.remove(l);
490 }
491
492 friend void AutoGCRooter::trace(JSTracer *trc);
493
494 private:
495 AutoHashSetRooter(const AutoHashSetRooter &hmr) MOZ_DELETE;
496 AutoHashSetRooter &operator=(const AutoHashSetRooter &hmr) MOZ_DELETE;
497
498 HashSetImpl set;
499
500 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
501 };
502
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 }
512
513 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
514 };
515
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 }
525
526 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
527 };
528
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 }
538
539 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
540 };
541
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 }
551
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 }
558
559 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
560 };
561
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 }
571
572 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
573 };
574
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 }
587
588 friend void AutoGCRooter::trace(JSTracer *trc);
589
590 protected:
591 /* Supplied by derived class to trace roots. */
592 virtual void trace(JSTracer *trc) = 0;
593
594 private:
595 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
596 };
597
598 /* A handle to an array of rooted values. */
599 class HandleValueArray
600 {
601 const size_t length_;
602 const Value * const elements_;
603
604 HandleValueArray(size_t len, const Value *elements) : length_(len), elements_(elements) {}
605
606 public:
607 HandleValueArray(const RootedValue& value) : length_(1), elements_(value.address()) {}
608
609 HandleValueArray(const AutoValueVector& values)
610 : length_(values.length()), elements_(values.begin()) {}
611
612 template <size_t N>
613 HandleValueArray(const AutoValueArray<N>& values) : length_(N), elements_(values.begin()) {}
614
615 /* CallArgs must already be rooted somewhere up the stack. */
616 HandleValueArray(const JS::CallArgs& args) : length_(args.length()), elements_(args.array()) {}
617
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 }
622
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 }
627
628 static HandleValueArray empty() {
629 return HandleValueArray(0, nullptr);
630 }
631
632 size_t length() const { return length_; }
633 const Value *begin() const { return elements_; }
634
635 HandleValue operator[](size_t i) const {
636 JS_ASSERT(i < length_);
637 return HandleValue::fromMarkedLocation(&elements_[i]);
638 }
639 };
640
641 } /* namespace JS */
642
643 /************************************************************************/
644
645 struct JSFreeOp {
646 private:
647 JSRuntime *runtime_;
648
649 protected:
650 JSFreeOp(JSRuntime *rt)
651 : runtime_(rt) { }
652
653 public:
654 JSRuntime *runtime() const {
655 return runtime_;
656 }
657 };
658
659 /* Callbacks and their arguments. */
660
661 /************************************************************************/
662
663 typedef enum JSContextOp {
664 JSCONTEXT_NEW,
665 JSCONTEXT_DESTROY
666 } JSContextOp;
667
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);
683
684 typedef enum JSGCStatus {
685 JSGC_BEGIN,
686 JSGC_END
687 } JSGCStatus;
688
689 typedef void
690 (* JSGCCallback)(JSRuntime *rt, JSGCStatus status, void *data);
691
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,
699
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,
707
708 /*
709 * Called at the end of collection when everything has been swept.
710 */
711 JSFINALIZE_COLLECTION_END
712 } JSFinalizeStatus;
713
714 typedef void
715 (* JSFinalizeCallback)(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment);
716
717 typedef bool
718 (* JSInterruptCallback)(JSContext *cx);
719
720 typedef void
721 (* JSErrorReporter)(JSContext *cx, const char *message, JSErrorReport *report);
722
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
730
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;
748
749 typedef struct JSErrorFormatString {
750 /* The error format string in ASCII. */
751 const char *format;
752
753 /* The number of arguments to expand in the formatted error message. */
754 uint16_t argCount;
755
756 /* One of the JSExnType constants above. */
757 int16_t exnType;
758 } JSErrorFormatString;
759
760 typedef const JSErrorFormatString *
761 (* JSErrorCallback)(void *userRef, const char *locale,
762 const unsigned errorNumber);
763
764 typedef bool
765 (* JSLocaleToUpperCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
766
767 typedef bool
768 (* JSLocaleToLowerCase)(JSContext *cx, JS::HandleString src, JS::MutableHandleValue rval);
769
770 typedef bool
771 (* JSLocaleCompare)(JSContext *cx, JS::HandleString src1, JS::HandleString src2,
772 JS::MutableHandleValue rval);
773
774 typedef bool
775 (* JSLocaleToUnicode)(JSContext *cx, const char *src, JS::MutableHandleValue rval);
776
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);
790
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);
799
800 struct JSWrapObjectCallbacks
801 {
802 JSWrapObjectCallback wrap;
803 JSPreWrapCallback preWrap;
804 };
805
806 typedef void
807 (* JSDestroyCompartmentCallback)(JSFreeOp *fop, JSCompartment *compartment);
808
809 typedef void
810 (* JSZoneCallback)(JS::Zone *zone);
811
812 typedef void
813 (* JSCompartmentNameCallback)(JSRuntime *rt, JSCompartment *compartment,
814 char *buf, size_t bufsize);
815
816 /************************************************************************/
817
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 }
827
828 /************************************************************************/
829
830 JS_PUBLIC_API(bool)
831 JS_StringHasBeenInterned(JSContext *cx, JSString *str);
832
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);
842
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 }
852
853 namespace JS {
854
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 }
864
865 jsid id() {
866 return id_;
867 }
868
869 jsid * addr() {
870 return &id_;
871 }
872
873 friend void AutoGCRooter::trace(JSTracer *trc);
874
875 private:
876 jsid id_;
877 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
878 };
879
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 };
907
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 }
922
923 ~SourceBufferHolder() {
924 if (ownsChars_)
925 js_free(const_cast<jschar *>(data_));
926 }
927
928 // Access the underlying source buffer without affecting ownership.
929 const jschar *get() const { return data_; }
930
931 // Length of the source buffer in jschars (not bytes)
932 size_t length() const { return length_; }
933
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_; }
937
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 }
955
956 private:
957 SourceBufferHolder(SourceBufferHolder &) MOZ_DELETE;
958 SourceBufferHolder &operator=(SourceBufferHolder &) MOZ_DELETE;
959
960 const jschar *data_;
961 size_t length_;
962 bool ownsChars_;
963 };
964
965 } /* namespace JS */
966
967 /************************************************************************/
968
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 */
986
987 #define JSFUN_STUB_GSOPS 0x200 /* use JS_PropertyStub getter/setter
988 instead of defaulting to class gsops
989 for property holding function */
990
991 #define JSFUN_CONSTRUCTOR 0x400 /* native that can be called as a ctor */
992
993
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
1005
1006 #define JSFUN_FLAGS_MASK 0xe00 /* | of all the JSFUN_* flags */
1007
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);
1018
1019 /* Microseconds since the epoch, midnight, January 1, 1970 UTC. */
1020 extern JS_PUBLIC_API(int64_t)
1021 JS_Now(void);
1022
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);
1026
1027 extern JS_PUBLIC_API(jsval)
1028 JS_GetNegativeInfinityValue(JSContext *cx);
1029
1030 extern JS_PUBLIC_API(jsval)
1031 JS_GetPositiveInfinityValue(JSContext *cx);
1032
1033 extern JS_PUBLIC_API(jsval)
1034 JS_GetEmptyStringValue(JSContext *cx);
1035
1036 extern JS_PUBLIC_API(JSString *)
1037 JS_GetEmptyString(JSRuntime *rt);
1038
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, ...);
1073
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
1079
1080 extern JS_PUBLIC_API(bool)
1081 JS_ConvertValue(JSContext *cx, JS::HandleValue v, JSType type, JS::MutableHandleValue vp);
1082
1083 extern JS_PUBLIC_API(bool)
1084 JS_ValueToObject(JSContext *cx, JS::HandleValue v, JS::MutableHandleObject objp);
1085
1086 extern JS_PUBLIC_API(JSFunction *)
1087 JS_ValueToFunction(JSContext *cx, JS::HandleValue v);
1088
1089 extern JS_PUBLIC_API(JSFunction *)
1090 JS_ValueToConstructor(JSContext *cx, JS::HandleValue v);
1091
1092 extern JS_PUBLIC_API(JSString *)
1093 JS_ValueToSource(JSContext *cx, JS::Handle<JS::Value> v);
1094
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);
1101
1102 /*
1103 * DO NOT CALL THIS. Use JS::ToBoolean
1104 */
1105 extern JS_PUBLIC_API(bool)
1106 ToBooleanSlow(JS::HandleValue v);
1107
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 */
1114
1115 namespace JS {
1116
1117 /* ES5 9.3 ToNumber. */
1118 MOZ_ALWAYS_INLINE bool
1119 ToNumber(JSContext *cx, HandleValue v, double *out)
1120 {
1121 AssertArgumentsAreSane(cx, v);
1122
1123 if (v.isNumber()) {
1124 *out = v.toNumber();
1125 return true;
1126 }
1127 return js::ToNumberSlow(cx, v, out);
1128 }
1129
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 }
1143
1144 /* The slow path handles strings and objects. */
1145 return js::ToBooleanSlow(v);
1146 }
1147
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 }
1155
1156 } /* namespace JS */
1157
1158 extern JS_PUBLIC_API(bool)
1159 JS_DoubleIsInt32(double d, int32_t *ip);
1160
1161 extern JS_PUBLIC_API(int32_t)
1162 JS_DoubleToInt32(double d);
1163
1164 extern JS_PUBLIC_API(uint32_t)
1165 JS_DoubleToUint32(double d);
1166
1167
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);
1172
1173 /* DO NOT CALL THIS. Use JS::ToInt32. */
1174 extern JS_PUBLIC_API(bool)
1175 ToInt32Slow(JSContext *cx, JS::HandleValue v, int32_t *out);
1176
1177 /* DO NOT CALL THIS. Use JS::ToUint32. */
1178 extern JS_PUBLIC_API(bool)
1179 ToUint32Slow(JSContext *cx, JS::HandleValue v, uint32_t *out);
1180
1181 /* DO NOT CALL THIS. Use JS::ToInt64. */
1182 extern JS_PUBLIC_API(bool)
1183 ToInt64Slow(JSContext *cx, JS::HandleValue v, int64_t *out);
1184
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 */
1189
1190 namespace JS {
1191
1192 MOZ_ALWAYS_INLINE bool
1193 ToUint16(JSContext *cx, JS::HandleValue v, uint16_t *out)
1194 {
1195 AssertArgumentsAreSane(cx, v);
1196
1197 if (v.isInt32()) {
1198 *out = uint16_t(v.toInt32());
1199 return true;
1200 }
1201 return js::ToUint16Slow(cx, v, out);
1202 }
1203
1204 MOZ_ALWAYS_INLINE bool
1205 ToInt32(JSContext *cx, JS::HandleValue v, int32_t *out)
1206 {
1207 AssertArgumentsAreSane(cx, v);
1208
1209 if (v.isInt32()) {
1210 *out = v.toInt32();
1211 return true;
1212 }
1213 return js::ToInt32Slow(cx, v, out);
1214 }
1215
1216 MOZ_ALWAYS_INLINE bool
1217 ToUint32(JSContext *cx, JS::HandleValue v, uint32_t *out)
1218 {
1219 AssertArgumentsAreSane(cx, v);
1220
1221 if (v.isInt32()) {
1222 *out = uint32_t(v.toInt32());
1223 return true;
1224 }
1225 return js::ToUint32Slow(cx, v, out);
1226 }
1227
1228 MOZ_ALWAYS_INLINE bool
1229 ToInt64(JSContext *cx, JS::HandleValue v, int64_t *out)
1230 {
1231 AssertArgumentsAreSane(cx, v);
1232
1233 if (v.isInt32()) {
1234 *out = int64_t(v.toInt32());
1235 return true;
1236 }
1237 return js::ToInt64Slow(cx, v, out);
1238 }
1239
1240 MOZ_ALWAYS_INLINE bool
1241 ToUint64(JSContext *cx, JS::HandleValue v, uint64_t *out)
1242 {
1243 AssertArgumentsAreSane(cx, v);
1244
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 }
1252
1253
1254 } /* namespace JS */
1255
1256 extern JS_PUBLIC_API(JSType)
1257 JS_TypeOfValue(JSContext *cx, JS::Handle<JS::Value> v);
1258
1259 extern JS_PUBLIC_API(const char *)
1260 JS_GetTypeName(JSContext *cx, JSType type);
1261
1262 extern JS_PUBLIC_API(bool)
1263 JS_StrictlyEqual(JSContext *cx, jsval v1, jsval v2, bool *equal);
1264
1265 extern JS_PUBLIC_API(bool)
1266 JS_LooselyEqual(JSContext *cx, JS::Handle<JS::Value> v1, JS::Handle<JS::Value> v2, bool *equal);
1267
1268 extern JS_PUBLIC_API(bool)
1269 JS_SameValue(JSContext *cx, jsval v1, jsval v2, bool *same);
1270
1271 /* True iff fun is the global eval function. */
1272 extern JS_PUBLIC_API(bool)
1273 JS_IsBuiltinEvalFunction(JSFunction *fun);
1274
1275 /* True iff fun is the Function constructor. */
1276 extern JS_PUBLIC_API(bool)
1277 JS_IsBuiltinFunctionConstructor(JSFunction *fun);
1278
1279 /************************************************************************/
1280
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 */
1288
1289 typedef enum JSUseHelperThreads
1290 {
1291 JS_NO_HELPER_THREADS,
1292 JS_USE_HELPER_THREADS
1293 } JSUseHelperThreads;
1294
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);
1310
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);
1330
1331 extern JS_PUBLIC_API(JSRuntime *)
1332 JS_NewRuntime(uint32_t maxbytes, JSUseHelperThreads useHelperThreads,
1333 JSRuntime *parentRuntime = nullptr);
1334
1335 extern JS_PUBLIC_API(void)
1336 JS_DestroyRuntime(JSRuntime *rt);
1337
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);
1344
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);
1349
1350 JS_PUBLIC_API(void *)
1351 JS_GetRuntimePrivate(JSRuntime *rt);
1352
1353 extern JS_PUBLIC_API(JSRuntime *)
1354 JS_GetRuntime(JSContext *cx);
1355
1356 extern JS_PUBLIC_API(JSRuntime *)
1357 JS_GetParentRuntime(JSContext *cx);
1358
1359 JS_PUBLIC_API(void)
1360 JS_SetRuntimePrivate(JSRuntime *rt, void *data);
1361
1362 extern JS_PUBLIC_API(void)
1363 JS_BeginRequest(JSContext *cx);
1364
1365 extern JS_PUBLIC_API(void)
1366 JS_EndRequest(JSContext *cx);
1367
1368 extern JS_PUBLIC_API(bool)
1369 JS_IsInRequest(JSRuntime *rt);
1370
1371 namespace js {
1372
1373 void
1374 AssertHeapIsIdle(JSRuntime *rt);
1375
1376 void
1377 AssertHeapIsIdle(JSContext *cx);
1378
1379 } /* namespace js */
1380
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 }
1394
1395 protected:
1396 JSContext *mContext;
1397 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1398
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 };
1405
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 }
1418
1419 ~JSAutoCheckRequest() {
1420 #if defined JS_THREADSAFE && defined JS_DEBUG
1421 JS_ASSERT(JS_IsInRequest(JS_GetRuntime(mContext)));
1422 #endif
1423 }
1424
1425
1426 private:
1427 #if defined JS_THREADSAFE && defined JS_DEBUG
1428 JSContext *mContext;
1429 #endif
1430 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
1431 };
1432
1433 extern JS_PUBLIC_API(void)
1434 JS_SetContextCallback(JSRuntime *rt, JSContextCallback cxCallback, void *data);
1435
1436 extern JS_PUBLIC_API(JSContext *)
1437 JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
1438
1439 extern JS_PUBLIC_API(void)
1440 JS_DestroyContext(JSContext *cx);
1441
1442 extern JS_PUBLIC_API(void)
1443 JS_DestroyContextNoGC(JSContext *cx);
1444
1445 extern JS_PUBLIC_API(void *)
1446 JS_GetContextPrivate(JSContext *cx);
1447
1448 extern JS_PUBLIC_API(void)
1449 JS_SetContextPrivate(JSContext *cx, void *data);
1450
1451 extern JS_PUBLIC_API(void *)
1452 JS_GetSecondContextPrivate(JSContext *cx);
1453
1454 extern JS_PUBLIC_API(void)
1455 JS_SetSecondContextPrivate(JSContext *cx, void *data);
1456
1457 extern JS_PUBLIC_API(JSRuntime *)
1458 JS_GetRuntime(JSContext *cx);
1459
1460 extern JS_PUBLIC_API(JSContext *)
1461 JS_ContextIterator(JSRuntime *rt, JSContext **iterp);
1462
1463 extern JS_PUBLIC_API(JSVersion)
1464 JS_GetVersion(JSContext *cx);
1465
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);
1474
1475 extern JS_PUBLIC_API(const char *)
1476 JS_VersionToString(JSVersion version);
1477
1478 extern JS_PUBLIC_API(JSVersion)
1479 JS_StringToVersion(const char *string);
1480
1481 namespace JS {
1482
1483 class JS_PUBLIC_API(RuntimeOptions) {
1484 public:
1485 RuntimeOptions()
1486 : baseline_(false),
1487 ion_(false),
1488 asmJS_(false)
1489 {
1490 }
1491
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 }
1501
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 }
1511
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 }
1521
1522 private:
1523 bool baseline_ : 1;
1524 bool ion_ : 1;
1525 bool asmJS_ : 1;
1526 };
1527
1528 JS_PUBLIC_API(RuntimeOptions &)
1529 RuntimeOptionsRef(JSRuntime *rt);
1530
1531 JS_PUBLIC_API(RuntimeOptions &)
1532 RuntimeOptionsRef(JSContext *cx);
1533
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 }
1548
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 }
1558
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 }
1568
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 }
1578
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 }
1588
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 }
1598
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 }
1608
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 }
1618
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 }
1628
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 }
1638
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 };
1650
1651 JS_PUBLIC_API(ContextOptions &)
1652 ContextOptionsRef(JSContext *cx);
1653
1654 class JS_PUBLIC_API(AutoSaveContextOptions) {
1655 public:
1656 AutoSaveContextOptions(JSContext *cx)
1657 : cx_(cx),
1658 oldOptions_(ContextOptionsRef(cx_))
1659 {
1660 }
1661
1662 ~AutoSaveContextOptions()
1663 {
1664 ContextOptionsRef(cx_) = oldOptions_;
1665 }
1666
1667 private:
1668 JSContext *cx_;
1669 JS::ContextOptions oldOptions_;
1670 };
1671
1672 } /* namespace JS */
1673
1674 extern JS_PUBLIC_API(const char *)
1675 JS_GetImplementationVersion(void);
1676
1677 extern JS_PUBLIC_API(void)
1678 JS_SetDestroyCompartmentCallback(JSRuntime *rt, JSDestroyCompartmentCallback callback);
1679
1680 extern JS_PUBLIC_API(void)
1681 JS_SetDestroyZoneCallback(JSRuntime *rt, JSZoneCallback callback);
1682
1683 extern JS_PUBLIC_API(void)
1684 JS_SetSweepZoneCallback(JSRuntime *rt, JSZoneCallback callback);
1685
1686 extern JS_PUBLIC_API(void)
1687 JS_SetCompartmentNameCallback(JSRuntime *rt, JSCompartmentNameCallback callback);
1688
1689 extern JS_PUBLIC_API(void)
1690 JS_SetWrapObjectCallbacks(JSRuntime *rt, const JSWrapObjectCallbacks *callbacks);
1691
1692 extern JS_PUBLIC_API(void)
1693 JS_SetCompartmentPrivate(JSCompartment *compartment, void *data);
1694
1695 extern JS_PUBLIC_API(void *)
1696 JS_GetCompartmentPrivate(JSCompartment *compartment);
1697
1698 extern JS_PUBLIC_API(void)
1699 JS_SetZoneUserData(JS::Zone *zone, void *data);
1700
1701 extern JS_PUBLIC_API(void *)
1702 JS_GetZoneUserData(JS::Zone *zone);
1703
1704 extern JS_PUBLIC_API(bool)
1705 JS_WrapObject(JSContext *cx, JS::MutableHandleObject objp);
1706
1707 extern JS_PUBLIC_API(bool)
1708 JS_WrapValue(JSContext *cx, JS::MutableHandleValue vp);
1709
1710 extern JS_PUBLIC_API(bool)
1711 JS_WrapId(JSContext *cx, JS::MutableHandleId idp);
1712
1713 extern JS_PUBLIC_API(JSObject *)
1714 JS_TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject target);
1715
1716 extern JS_PUBLIC_API(bool)
1717 JS_RefreshCrossCompartmentWrappers(JSContext *cx, JS::Handle<JSObject*> obj);
1718
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 */
1753
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 };
1763
1764 class JS_PUBLIC_API(JSAutoNullCompartment)
1765 {
1766 JSContext *cx_;
1767 JSCompartment *oldCompartment_;
1768 public:
1769 JSAutoNullCompartment(JSContext *cx);
1770 ~JSAutoNullCompartment();
1771 };
1772
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);
1776
1777 extern JS_PUBLIC_API(void)
1778 JS_LeaveCompartment(JSContext *cx, JSCompartment *oldCompartment);
1779
1780 typedef void (*JSIterateCompartmentCallback)(JSRuntime *rt, void *data, JSCompartment *compartment);
1781
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);
1790
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);
1800
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);
1816
1817 extern JS_PUBLIC_API(bool)
1818 JS_EnumerateStandardClasses(JSContext *cx, JS::HandleObject obj);
1819
1820 extern JS_PUBLIC_API(bool)
1821 JS_GetClassObject(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1822
1823 extern JS_PUBLIC_API(bool)
1824 JS_GetClassPrototype(JSContext *cx, JSProtoKey key, JS::MutableHandle<JSObject*> objp);
1825
1826 namespace JS {
1827
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 */
1832
1833 extern JS_PUBLIC_API(JSProtoKey)
1834 IdentifyStandardInstance(JSObject *obj);
1835
1836 extern JS_PUBLIC_API(JSProtoKey)
1837 IdentifyStandardPrototype(JSObject *obj);
1838
1839 extern JS_PUBLIC_API(JSProtoKey)
1840 IdentifyStandardInstanceOrPrototype(JSObject *obj);
1841
1842 } /* namespace JS */
1843
1844 extern JS_PUBLIC_API(JSProtoKey)
1845 JS_IdToProtoKey(JSContext *cx, JS::HandleId id);
1846
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);
1853
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);
1860
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);
1867
1868 extern JS_PUBLIC_API(JSObject *)
1869 JS_GetGlobalForObject(JSContext *cx, JSObject *obj);
1870
1871 extern JS_PUBLIC_API(bool)
1872 JS_IsGlobalObject(JSObject *obj);
1873
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);
1880
1881 namespace JS {
1882
1883 extern JS_PUBLIC_API(JSObject *)
1884 CurrentGlobalOrNull(JSContext *cx);
1885
1886 }
1887
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);
1893
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);
1901
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);
1909
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 };
1918
1919 typedef struct JSCTypesCallbacks JSCTypesCallbacks;
1920
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
1930
1931 typedef bool
1932 (* JSEnumerateDiagnosticMemoryCallback)(void *ptr, size_t length);
1933
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);
1940
1941 extern JS_PUBLIC_API(void *)
1942 JS_malloc(JSContext *cx, size_t nbytes);
1943
1944 extern JS_PUBLIC_API(void *)
1945 JS_realloc(JSContext *cx, void *p, size_t nbytes);
1946
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);
1954
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);
1961
1962 extern JS_PUBLIC_API(JSFreeOp *)
1963 JS_GetDefaultFreeOp(JSRuntime *rt);
1964
1965 extern JS_PUBLIC_API(void)
1966 JS_updateMallocCounter(JSContext *cx, size_t nbytes);
1967
1968 extern JS_PUBLIC_API(char *)
1969 JS_strdup(JSContext *cx, const char *s);
1970
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);
1974
1975 namespace JS {
1976
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);
2004
2005 extern JS_PUBLIC_API(bool)
2006 AddStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
2007
2008 extern JS_PUBLIC_API(bool)
2009 AddObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
2010
2011 extern JS_PUBLIC_API(bool)
2012 AddNamedValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp, const char *name);
2013
2014 extern JS_PUBLIC_API(bool)
2015 AddNamedValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp, const char *name);
2016
2017 extern JS_PUBLIC_API(bool)
2018 AddNamedStringRoot(JSContext *cx, JS::Heap<JSString *> *rp, const char *name);
2019
2020 extern JS_PUBLIC_API(bool)
2021 AddNamedObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp, const char *name);
2022
2023 extern JS_PUBLIC_API(bool)
2024 AddNamedScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp, const char *name);
2025
2026 extern JS_PUBLIC_API(void)
2027 RemoveValueRoot(JSContext *cx, JS::Heap<JS::Value> *vp);
2028
2029 extern JS_PUBLIC_API(void)
2030 RemoveStringRoot(JSContext *cx, JS::Heap<JSString *> *rp);
2031
2032 extern JS_PUBLIC_API(void)
2033 RemoveObjectRoot(JSContext *cx, JS::Heap<JSObject *> *rp);
2034
2035 extern JS_PUBLIC_API(void)
2036 RemoveScriptRoot(JSContext *cx, JS::Heap<JSScript *> *rp);
2037
2038 extern JS_PUBLIC_API(void)
2039 RemoveValueRootRT(JSRuntime *rt, JS::Heap<JS::Value> *vp);
2040
2041 extern JS_PUBLIC_API(void)
2042 RemoveStringRootRT(JSRuntime *rt, JS::Heap<JSString *> *rp);
2043
2044 extern JS_PUBLIC_API(void)
2045 RemoveObjectRootRT(JSRuntime *rt, JS::Heap<JSObject *> *rp);
2046
2047 extern JS_PUBLIC_API(void)
2048 RemoveScriptRootRT(JSRuntime *rt, JS::Heap<JSScript *> *rp);
2049
2050 } /* namespace JS */
2051
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);
2061
2062 /* Undo a call to JS_AddExtraGCRootsTracer. */
2063 extern JS_PUBLIC_API(void)
2064 JS_RemoveExtraGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
2065
2066 #ifdef JS_DEBUG
2067
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);
2086
2087 #endif
2088
2089 /*
2090 * Garbage collector API.
2091 */
2092 extern JS_PUBLIC_API(void)
2093 JS_GC(JSRuntime *rt);
2094
2095 extern JS_PUBLIC_API(void)
2096 JS_MaybeGC(JSContext *cx);
2097
2098 extern JS_PUBLIC_API(void)
2099 JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb, void *data);
2100
2101 extern JS_PUBLIC_API(void)
2102 JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
2103
2104 extern JS_PUBLIC_API(bool)
2105 JS_IsGCMarkingTracer(JSTracer *trc);
2106
2107 /* For assertions only. */
2108 #ifdef JS_DEBUG
2109 extern JS_PUBLIC_API(bool)
2110 JS_IsMarkingGray(JSTracer *trc);
2111 #endif
2112
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);
2131
2132 extern JS_PUBLIC_API(bool)
2133 JS_IsAboutToBeFinalizedUnbarriered(JSObject **objp);
2134
2135 typedef enum JSGCParamKey {
2136 /* Maximum nominal heap before last ditch GC. */
2137 JSGC_MAX_BYTES = 0,
2138
2139 /* Number of JS_malloc bytes before last ditch GC. */
2140 JSGC_MAX_MALLOC_BYTES = 1,
2141
2142 /* Amount of bytes allocated by the GC. */
2143 JSGC_BYTES = 3,
2144
2145 /* Number of times when GC was invoked. */
2146 JSGC_NUMBER = 4,
2147
2148 /* Max size of the code cache in bytes. */
2149 JSGC_MAX_CODE_CACHE_BYTES = 5,
2150
2151 /* Select GC mode. */
2152 JSGC_MODE = 6,
2153
2154 /* Number of cached empty GC chunks. */
2155 JSGC_UNUSED_CHUNKS = 7,
2156
2157 /* Total number of allocated GC chunks. */
2158 JSGC_TOTAL_CHUNKS = 8,
2159
2160 /* Max milliseconds to spend in an incremental GC slice. */
2161 JSGC_SLICE_TIME_BUDGET = 9,
2162
2163 /* Maximum size the GC mark stack can grow to. */
2164 JSGC_MARK_STACK_LIMIT = 10,
2165
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,
2171
2172 /* Start of dynamic heap growth. */
2173 JSGC_HIGH_FREQUENCY_LOW_LIMIT = 12,
2174
2175 /* End of dynamic heap growth. */
2176 JSGC_HIGH_FREQUENCY_HIGH_LIMIT = 13,
2177
2178 /* Upper bound of heap growth. */
2179 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX = 14,
2180
2181 /* Lower bound of heap growth. */
2182 JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN = 15,
2183
2184 /* Heap growth for low frequency GCs. */
2185 JSGC_LOW_FREQUENCY_HEAP_GROWTH = 16,
2186
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,
2192
2193 /* If true, high-frequency GCs will use a longer mark slice. */
2194 JSGC_DYNAMIC_MARK_SLICE = 18,
2195
2196 /* Lower limit after which we limit the heap growth. */
2197 JSGC_ALLOCATION_THRESHOLD = 19,
2198
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;
2206
2207 extern JS_PUBLIC_API(void)
2208 JS_SetGCParameter(JSRuntime *rt, JSGCParamKey key, uint32_t value);
2209
2210 extern JS_PUBLIC_API(uint32_t)
2211 JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key);
2212
2213 extern JS_PUBLIC_API(void)
2214 JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32_t value);
2215
2216 extern JS_PUBLIC_API(uint32_t)
2217 JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
2218
2219 extern JS_PUBLIC_API(void)
2220 JS_SetGCParametersBasedOnAvailableMemory(JSRuntime *rt, uint32_t availMem);
2221
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);
2229
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);
2236
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);
2243
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);
2263
2264 /************************************************************************/
2265
2266 extern JS_PUBLIC_API(int)
2267 JS_IdArrayLength(JSContext *cx, JSIdArray *ida);
2268
2269 extern JS_PUBLIC_API(jsid)
2270 JS_IdArrayGet(JSContext *cx, JSIdArray *ida, int index);
2271
2272 extern JS_PUBLIC_API(void)
2273 JS_DestroyIdArray(JSContext *cx, JSIdArray *ida);
2274
2275 namespace JS {
2276
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 }
2300
2301 friend void AutoGCRooter::trace(JSTracer *trc);
2302
2303 JSIdArray *steal() {
2304 JSIdArray *copy = idArray;
2305 idArray = nullptr;
2306 return copy;
2307 }
2308
2309 protected:
2310 inline void trace(JSTracer *trc);
2311
2312 private:
2313 JSContext *context;
2314 JSIdArray *idArray;
2315 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
2316
2317 /* No copy or assignment semantics. */
2318 AutoIdArray(AutoIdArray &ida) MOZ_DELETE;
2319 void operator=(AutoIdArray &ida) MOZ_DELETE;
2320 };
2321
2322 } /* namespace JS */
2323
2324 extern JS_PUBLIC_API(bool)
2325 JS_ValueToId(JSContext *cx, JS::HandleValue v, JS::MutableHandleId idp);
2326
2327 extern JS_PUBLIC_API(bool)
2328 JS_StringToId(JSContext *cx, JS::HandleString s, JS::MutableHandleId idp);
2329
2330 extern JS_PUBLIC_API(bool)
2331 JS_IdToValue(JSContext *cx, jsid id, JS::MutableHandle<JS::Value> vp);
2332
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);
2342
2343 extern JS_PUBLIC_API(bool)
2344 JS_PropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2345 JS::MutableHandleValue vp);
2346
2347 extern JS_PUBLIC_API(bool)
2348 JS_StrictPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
2349 JS::MutableHandleValue vp);
2350
2351 extern JS_PUBLIC_API(bool)
2352 JS_DeletePropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2353 bool *succeeded);
2354
2355 extern JS_PUBLIC_API(bool)
2356 JS_EnumerateStub(JSContext *cx, JS::HandleObject obj);
2357
2358 extern JS_PUBLIC_API(bool)
2359 JS_ResolveStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
2360
2361 extern JS_PUBLIC_API(bool)
2362 JS_ConvertStub(JSContext *cx, JS::HandleObject obj, JSType type,
2363 JS::MutableHandleValue vp);
2364
2365 struct JSConstDoubleSpec {
2366 double dval;
2367 const char *name;
2368 uint8_t flags;
2369 uint8_t spare[3];
2370 };
2371
2372 struct JSJitInfo;
2373
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;
2383
2384 typedef struct JSPropertyOpWrapper {
2385 JSPropertyOp op;
2386 const JSJitInfo *info;
2387 } JSPropertyOpWrapper;
2388
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;
2396
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)
2403
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 };
2414
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;
2425
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 };
2434
2435 namespace JS {
2436 namespace detail {
2437
2438 /* NEVER DEFINED, DON'T USE. For use by JS_CAST_NATIVE_TO only. */
2439 inline int CheckIsNative(JSNative native);
2440
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]);
2445
2446 } // namespace detail
2447 } // namespace JS
2448
2449 #define JS_CAST_NATIVE_TO(v, To) \
2450 (static_cast<void>(sizeof(JS::detail::CheckIsNative(v))), \
2451 reinterpret_cast<To>(v))
2452
2453 #define JS_CAST_STRING_TO(s, To) \
2454 (static_cast<void>(sizeof(JS::detail::CheckIsCharacterLiteral(s))), \
2455 reinterpret_cast<To>(s))
2456
2457 #define JS_CHECK_ACCESSOR_FLAGS(flags) \
2458 (static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))>::Type>(0), \
2459 (flags))
2460
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 }
2489
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 };
2502
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)
2508
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}
2526
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);
2532
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);
2540
2541 extern JS_PUBLIC_API(const JSClass *)
2542 JS_GetClass(JSObject *obj);
2543
2544 extern JS_PUBLIC_API(bool)
2545 JS_InstanceOf(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp, JS::CallArgs *args);
2546
2547 extern JS_PUBLIC_API(bool)
2548 JS_HasInstance(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JS::Value> v, bool *bp);
2549
2550 extern JS_PUBLIC_API(void *)
2551 JS_GetPrivate(JSObject *obj);
2552
2553 extern JS_PUBLIC_API(void)
2554 JS_SetPrivate(JSObject *obj, void *data);
2555
2556 extern JS_PUBLIC_API(void *)
2557 JS_GetInstancePrivate(JSContext *cx, JS::Handle<JSObject*> obj, const JSClass *clasp,
2558 JS::CallArgs *args);
2559
2560 extern JS_PUBLIC_API(bool)
2561 JS_GetPrototype(JSContext *cx, JS::HandleObject obj, JS::MutableHandleObject protop);
2562
2563 extern JS_PUBLIC_API(bool)
2564 JS_SetPrototype(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto);
2565
2566 extern JS_PUBLIC_API(JSObject *)
2567 JS_GetParent(JSObject *obj);
2568
2569 extern JS_PUBLIC_API(bool)
2570 JS_SetParent(JSContext *cx, JS::HandleObject obj, JS::HandleObject parent);
2571
2572 extern JS_PUBLIC_API(JSObject *)
2573 JS_GetConstructor(JSContext *cx, JS::Handle<JSObject*> proto);
2574
2575 namespace JS {
2576
2577 enum ZoneSpecifier {
2578 FreshZone = 0,
2579 SystemZone = 1
2580 };
2581
2582 class JS_PUBLIC_API(CompartmentOptions)
2583 {
2584 public:
2585 class Override {
2586 public:
2587 Override() : mode_(Default) {}
2588
2589 bool get(bool defaultValue) const {
2590 if (mode_ == Default)
2591 return defaultValue;
2592 return mode_ == ForceTrue;
2593 };
2594
2595 void set(bool overrideValue) {
2596 mode_ = overrideValue ? ForceTrue : ForceFalse;
2597 };
2598
2599 void reset() {
2600 mode_ = Default;
2601 }
2602
2603 private:
2604 enum Mode {
2605 Default,
2606 ForceTrue,
2607 ForceFalse
2608 };
2609
2610 Mode mode_;
2611 };
2612
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 }
2623
2624 JSVersion version() const { return version_; }
2625 CompartmentOptions &setVersion(JSVersion aVersion) {
2626 MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
2627 version_ = aVersion;
2628 return *this;
2629 }
2630
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 }
2640
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 }
2650
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 }
2658
2659
2660 bool cloneSingletons(JSContext *cx) const;
2661 Override &cloneSingletonsOverride() { return cloneSingletonsOverride_; }
2662
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);
2670
2671 void setSingletonsAsValues() {
2672 singletonsAsTemplates_ = false;
2673 }
2674 bool getSingletonsAsTemplates() const {
2675 return singletonsAsTemplates_;
2676 };
2677
2678 CompartmentOptions &setTrace(JSTraceOp op) {
2679 traceGlobal_ = op;
2680 return *this;
2681 }
2682 JSTraceOp getTrace() const {
2683 return traceGlobal_;
2684 }
2685
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_;
2697
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 };
2703
2704 JS_PUBLIC_API(CompartmentOptions &)
2705 CompartmentOptionsRef(JSCompartment *compartment);
2706
2707 JS_PUBLIC_API(CompartmentOptions &)
2708 CompartmentOptionsRef(JSObject *obj);
2709
2710 JS_PUBLIC_API(CompartmentOptions &)
2711 CompartmentOptionsRef(JSContext *cx);
2712
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 };
2737
2738 } /* namespace JS */
2739
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);
2755
2756 extern JS_PUBLIC_API(void)
2757 JS_FireOnNewGlobalObject(JSContext *cx, JS::HandleObject global);
2758
2759 extern JS_PUBLIC_API(JSObject *)
2760 JS_NewObject(JSContext *cx, const JSClass *clasp, JS::Handle<JSObject*> proto,
2761 JS::Handle<JSObject*> parent);
2762
2763 /* Queries the [[Extensible]] property of the object. */
2764 extern JS_PUBLIC_API(bool)
2765 JS_IsExtensible(JSContext *cx, JS::HandleObject obj, bool *extensible);
2766
2767 extern JS_PUBLIC_API(bool)
2768 JS_IsNative(JSObject *obj);
2769
2770 extern JS_PUBLIC_API(JSRuntime *)
2771 JS_GetObjectRuntime(JSObject *obj);
2772
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);
2780
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);
2788
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);
2794
2795 extern JS_PUBLIC_API(bool)
2796 JS_PreventExtensions(JSContext *cx, JS::HandleObject obj);
2797
2798 extern JS_PUBLIC_API(JSObject *)
2799 JS_New(JSContext *cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
2800
2801 extern JS_PUBLIC_API(JSObject *)
2802 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp,
2803 JSObject *proto, unsigned attrs);
2804
2805 extern JS_PUBLIC_API(bool)
2806 JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
2807
2808 extern JS_PUBLIC_API(bool)
2809 JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *ps);
2810
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);
2815
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);
2820
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);
2825
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);
2830
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);
2835
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);
2840
2841 extern JS_PUBLIC_API(bool)
2842 JS_DefinePropertyById(JSContext *cx, JSObject *obj, jsid id, jsval value,
2843 JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
2844
2845 extern JS_PUBLIC_API(bool)
2846 JS_DefineOwnProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2847 JS::HandleValue descriptor, bool *bp);
2848
2849 extern JS_PUBLIC_API(bool)
2850 JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
2851 bool *foundp);
2852
2853 extern JS_PUBLIC_API(bool)
2854 JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2855 bool *foundp);
2856
2857 extern JS_PUBLIC_API(bool)
2858 JS_HasProperty(JSContext *cx, JS::HandleObject obj, const char *name, bool *foundp);
2859
2860 extern JS_PUBLIC_API(bool)
2861 JS_HasPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
2862
2863 extern JS_PUBLIC_API(bool)
2864 JS_LookupProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
2865
2866 extern JS_PUBLIC_API(bool)
2867 JS_LookupPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
2868 JS::MutableHandleValue vp);
2869
2870 struct JSPropertyDescriptor {
2871 JSObject *obj;
2872 unsigned attrs;
2873 JSPropertyOp getter;
2874 JSStrictPropertyOp setter;
2875 JS::Value value;
2876
2877 JSPropertyDescriptor()
2878 : obj(nullptr), attrs(0), getter(nullptr), setter(nullptr), value(JSVAL_VOID)
2879 {}
2880
2881 void trace(JSTracer *trc);
2882 };
2883
2884 namespace JS {
2885
2886 template <typename Outer>
2887 class PropertyDescriptorOperations
2888 {
2889 const JSPropertyDescriptor * desc() const { return static_cast<const Outer*>(this)->extract(); }
2890
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; }
2902
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 };
2923
2924 template <typename Outer>
2925 class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<Outer>
2926 {
2927 JSPropertyDescriptor * desc() { return static_cast<Outer*>(this)->extractMutable(); }
2928
2929 public:
2930
2931 void clear() {
2932 object().set(nullptr);
2933 setAttributes(0);
2934 setGetter(nullptr);
2935 setSetter(nullptr);
2936 value().setUndefined();
2937 }
2938
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 }
2948
2949 void setEnumerable() { desc()->attrs |= JSPROP_ENUMERATE; }
2950 void setAttributes(unsigned attrs) { desc()->attrs = attrs; }
2951
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 };
2957
2958 } /* namespace JS */
2959
2960 namespace js {
2961
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 };
2973
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 };
2987
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 };
2997
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 };
3011
3012 } /* namespace js */
3013
3014 extern JS_PUBLIC_API(bool)
3015 JS_GetOwnPropertyDescriptorById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
3016 JS::MutableHandle<JSPropertyDescriptor> desc);
3017
3018 extern JS_PUBLIC_API(bool)
3019 JS_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
3020 JS::MutableHandle<JSPropertyDescriptor> desc);
3021
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);
3030
3031 extern JS_PUBLIC_API(bool)
3032 JS_GetPropertyDescriptor(JSContext *cx, JS::HandleObject obj, const char *name,
3033 JS::MutableHandle<JSPropertyDescriptor> desc);
3034
3035 extern JS_PUBLIC_API(bool)
3036 JS_GetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::MutableHandleValue vp);
3037
3038 extern JS_PUBLIC_API(bool)
3039 JS_GetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp);
3040
3041 extern JS_PUBLIC_API(bool)
3042 JS_ForwardGetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject onBehalfOf,
3043 JS::MutableHandleValue vp);
3044
3045 extern JS_PUBLIC_API(bool)
3046 JS_SetProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue v);
3047
3048 extern JS_PUBLIC_API(bool)
3049 JS_SetPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
3050
3051 extern JS_PUBLIC_API(bool)
3052 JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
3053
3054 extern JS_PUBLIC_API(bool)
3055 JS_DeleteProperty2(JSContext *cx, JS::HandleObject obj, const char *name, bool *succeeded);
3056
3057 extern JS_PUBLIC_API(bool)
3058 JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
3059
3060 extern JS_PUBLIC_API(bool)
3061 JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
3062
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);
3068
3069 extern JS_PUBLIC_API(bool)
3070 JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
3071 size_t namelen, bool *foundp);
3072
3073 extern JS_PUBLIC_API(bool)
3074 JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
3075 const jschar *name, size_t namelen,
3076 bool *vp);
3077
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);
3082
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);
3087
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);
3092
3093 extern JS_PUBLIC_API(bool)
3094 JS_DeleteUCProperty2(JSContext *cx, JS::HandleObject obj, const jschar *name, size_t namelen,
3095 bool *succeeded);
3096
3097 extern JS_PUBLIC_API(JSObject *)
3098 JS_NewArrayObject(JSContext *cx, const JS::HandleValueArray& contents);
3099
3100 extern JS_PUBLIC_API(JSObject *)
3101 JS_NewArrayObject(JSContext *cx, size_t length);
3102
3103 extern JS_PUBLIC_API(bool)
3104 JS_IsArrayObject(JSContext *cx, JS::HandleValue value);
3105
3106 extern JS_PUBLIC_API(bool)
3107 JS_IsArrayObject(JSContext *cx, JS::HandleObject obj);
3108
3109 extern JS_PUBLIC_API(bool)
3110 JS_GetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t *lengthp);
3111
3112 extern JS_PUBLIC_API(bool)
3113 JS_SetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t length);
3114
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);
3118
3119 extern JS_PUBLIC_API(bool)
3120 JS_AlreadyHasOwnElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
3121
3122 extern JS_PUBLIC_API(bool)
3123 JS_HasElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
3124
3125 extern JS_PUBLIC_API(bool)
3126 JS_LookupElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
3127
3128 extern JS_PUBLIC_API(bool)
3129 JS_GetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp);
3130
3131 extern JS_PUBLIC_API(bool)
3132 JS_ForwardGetElementTo(JSContext *cx, JS::HandleObject obj, uint32_t index,
3133 JS::HandleObject onBehalfOf, JS::MutableHandleValue vp);
3134
3135 extern JS_PUBLIC_API(bool)
3136 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue v);
3137
3138 extern JS_PUBLIC_API(bool)
3139 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleObject v);
3140
3141 extern JS_PUBLIC_API(bool)
3142 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleString v);
3143
3144 extern JS_PUBLIC_API(bool)
3145 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, int32_t v);
3146
3147 extern JS_PUBLIC_API(bool)
3148 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, uint32_t v);
3149
3150 extern JS_PUBLIC_API(bool)
3151 JS_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, double v);
3152
3153 extern JS_PUBLIC_API(bool)
3154 JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index);
3155
3156 extern JS_PUBLIC_API(bool)
3157 JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
3158
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);
3165
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);
3172
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);
3179
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);
3188
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);
3197
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);
3205
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);
3212
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);
3219
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);
3229
3230 extern JS_PUBLIC_API(JSIdArray *)
3231 JS_Enumerate(JSContext *cx, JS::HandleObject obj);
3232
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);
3240
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);
3248
3249 extern JS_PUBLIC_API(jsval)
3250 JS_GetReservedSlot(JSObject *obj, uint32_t index);
3251
3252 extern JS_PUBLIC_API(void)
3253 JS_SetReservedSlot(JSObject *obj, uint32_t index, jsval v);
3254
3255 /************************************************************************/
3256
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);
3263
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);
3271
3272 namespace JS {
3273
3274 extern JS_PUBLIC_API(JSFunction *)
3275 GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, JS::Handle<jsid> id,
3276 unsigned nargs);
3277
3278 } /* namespace JS */
3279
3280 extern JS_PUBLIC_API(JSObject *)
3281 JS_GetFunctionObject(JSFunction *fun);
3282
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);
3291
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);
3301
3302 /*
3303 * Return the arity (length) of fun.
3304 */
3305 extern JS_PUBLIC_API(uint16_t)
3306 JS_GetFunctionArity(JSFunction *fun);
3307
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);
3316
3317 extern JS_PUBLIC_API(bool)
3318 JS_ObjectIsCallable(JSContext *cx, JSObject *obj);
3319
3320 extern JS_PUBLIC_API(bool)
3321 JS_IsNativeFunction(JSObject *funobj, JSNative call);
3322
3323 /* Return whether the given function is a valid constructor. */
3324 extern JS_PUBLIC_API(bool)
3325 JS_IsConstructor(JSFunction *fun);
3326
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);
3334
3335 extern JS_PUBLIC_API(bool)
3336 JS_DefineFunctions(JSContext *cx, JS::Handle<JSObject*> obj, const JSFunctionSpec *fs);
3337
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);
3341
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);
3346
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);
3350
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);
3357
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);
3368
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);
3373
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);
3378
3379 extern JS_PUBLIC_API(JSObject *)
3380 JS_GetGlobalFromScript(JSScript *script);
3381
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);
3387
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);
3393
3394 namespace JS {
3395
3396 /* Options for JavaScript compilation. */
3397
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 */
3431
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;
3443
3444 protected:
3445 JSPrincipals *originPrincipals_;
3446 const char *filename_;
3447 const char *introducerFilename_;
3448 const jschar *sourceMapURL_;
3449
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 { }
3482
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);
3486
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;
3497
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;
3517
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;
3524
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;
3528
3529 private:
3530 static JSObject * const nullObjectPtr;
3531 void operator=(const ReadOnlyCompileOptions &) MOZ_DELETE;
3532 };
3533
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;
3553
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();
3561
3562 JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
3563 JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
3564 JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
3565
3566 // Set this to a copy of |rhs|. Return false on OOM.
3567 bool copy(JSContext *cx, const ReadOnlyCompileOptions &rhs);
3568
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);
3574
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 }
3622
3623 virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
3624
3625 private:
3626 void operator=(const CompileOptions &rhs) MOZ_DELETE;
3627 };
3628
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;
3641
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);
3649
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 }
3657
3658 JSObject *element() const MOZ_OVERRIDE { return elementRoot; }
3659 JSString *elementAttributeName() const MOZ_OVERRIDE { return elementAttributeNameRoot; }
3660 JSScript *introductionScript() const MOZ_OVERRIDE { return introductionScriptRoot; }
3661
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 }
3707
3708 virtual bool wrap(JSContext *cx, JSCompartment *compartment) MOZ_OVERRIDE;
3709
3710 private:
3711 void operator=(const CompileOptions &rhs) MOZ_DELETE;
3712 };
3713
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);
3720
3721 extern JS_PUBLIC_API(JSScript *)
3722 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3723 const char *bytes, size_t length);
3724
3725 extern JS_PUBLIC_API(JSScript *)
3726 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3727 const jschar *chars, size_t length);
3728
3729 extern JS_PUBLIC_API(JSScript *)
3730 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, FILE *file);
3731
3732 extern JS_PUBLIC_API(JSScript *)
3733 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename);
3734
3735 extern JS_PUBLIC_API(bool)
3736 CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length);
3737
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 */
3753
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);
3758
3759 extern JS_PUBLIC_API(JSScript *)
3760 FinishOffThreadScript(JSContext *maybecx, JSRuntime *rt, void *token);
3761
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);
3766
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);
3771
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);
3776
3777 } /* namespace JS */
3778
3779 extern JS_PUBLIC_API(JSString *)
3780 JS_DecompileScript(JSContext *cx, JS::Handle<JSScript*> script, const char *name, unsigned indent);
3781
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)
3787
3788 extern JS_PUBLIC_API(JSString *)
3789 JS_DecompileFunction(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
3790
3791 extern JS_PUBLIC_API(JSString *)
3792 JS_DecompileFunctionBody(JSContext *cx, JS::Handle<JSFunction*> fun, unsigned indent);
3793
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);
3829
3830 extern JS_PUBLIC_API(bool)
3831 JS_ExecuteScript(JSContext *cx, JS::HandleObject obj, JS::HandleScript script);
3832
3833 namespace JS {
3834
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);
3841
3842 } /* namespace JS */
3843
3844 extern JS_PUBLIC_API(bool)
3845 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
3846 JS::MutableHandleValue rval, JSVersion version);
3847
3848 extern JS_PUBLIC_API(bool)
3849 JS_ExecuteScriptVersion(JSContext *cx, JS::HandleObject obj, JS::HandleScript script,
3850 JSVersion version);
3851
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);
3857
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);
3862
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);
3868
3869 namespace JS {
3870
3871 extern JS_PUBLIC_API(bool)
3872 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3873 SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
3874
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);
3878
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);
3882
3883 extern JS_PUBLIC_API(bool)
3884 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3885 const char *filename, JS::MutableHandleValue rval);
3886
3887 extern JS_PUBLIC_API(bool)
3888 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3889 SourceBufferHolder &srcBuf);
3890
3891 extern JS_PUBLIC_API(bool)
3892 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3893 const jschar *chars, size_t length);
3894
3895 extern JS_PUBLIC_API(bool)
3896 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3897 const char *bytes, size_t length);
3898
3899 extern JS_PUBLIC_API(bool)
3900 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
3901 const char *filename);
3902
3903 } /* namespace JS */
3904
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);
3908
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);
3912
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);
3916
3917 namespace JS {
3918
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 }
3925
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 }
3932
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 }
3939
3940 extern JS_PUBLIC_API(bool)
3941 Call(JSContext *cx, JS::HandleValue thisv, JS::HandleValue fun, const JS::HandleValueArray& args,
3942 MutableHandleValue rval);
3943
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 }
3952
3953 } /* namespace JS */
3954
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);
3970
3971 extern JS_PUBLIC_API(JSInterruptCallback)
3972 JS_GetInterruptCallback(JSRuntime *rt);
3973
3974 extern JS_PUBLIC_API(void)
3975 JS_RequestInterruptCallback(JSRuntime *rt);
3976
3977 extern JS_PUBLIC_API(bool)
3978 JS_IsRunning(JSContext *cx);
3979
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);
3993
3994 extern JS_PUBLIC_API(void)
3995 JS_RestoreFrameChain(JSContext *cx);
3996
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);
4009
4010 extern JS_PUBLIC_API(JSFunctionCallback)
4011 JS_GetFunctionCallback(JSContext *cx);
4012 #endif /* MOZ_TRACE_JSCALLS */
4013
4014 /************************************************************************/
4015
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);
4027
4028 extern JS_PUBLIC_API(JSString *)
4029 JS_NewStringCopyZ(JSContext *cx, const char *s);
4030
4031 extern JS_PUBLIC_API(JSString *)
4032 JS_InternJSString(JSContext *cx, JS::HandleString str);
4033
4034 extern JS_PUBLIC_API(JSString *)
4035 JS_InternStringN(JSContext *cx, const char *s, size_t length);
4036
4037 extern JS_PUBLIC_API(JSString *)
4038 JS_InternString(JSContext *cx, const char *s);
4039
4040 extern JS_PUBLIC_API(JSString *)
4041 JS_NewUCString(JSContext *cx, jschar *chars, size_t length);
4042
4043 extern JS_PUBLIC_API(JSString *)
4044 JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n);
4045
4046 extern JS_PUBLIC_API(JSString *)
4047 JS_NewUCStringCopyZ(JSContext *cx, const jschar *s);
4048
4049 extern JS_PUBLIC_API(JSString *)
4050 JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length);
4051
4052 extern JS_PUBLIC_API(JSString *)
4053 JS_InternUCString(JSContext *cx, const jschar *s);
4054
4055 extern JS_PUBLIC_API(bool)
4056 JS_CompareStrings(JSContext *cx, JSString *str1, JSString *str2, int32_t *result);
4057
4058 extern JS_PUBLIC_API(bool)
4059 JS_StringEqualsAscii(JSContext *cx, JSString *str, const char *asciiBytes, bool *match);
4060
4061 extern JS_PUBLIC_API(size_t)
4062 JS_PutEscapedString(JSContext *cx, char *buffer, size_t size, JSString *str, char quote);
4063
4064 extern JS_PUBLIC_API(bool)
4065 JS_FileEscapedString(FILE *fp, JSString *str, char quote);
4066
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 */
4101
4102 extern JS_PUBLIC_API(size_t)
4103 JS_GetStringLength(JSString *str);
4104
4105 extern JS_PUBLIC_API(const jschar *)
4106 JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *length);
4107
4108 extern JS_PUBLIC_API(const jschar *)
4109 JS_GetInternedStringChars(JSString *str);
4110
4111 extern JS_PUBLIC_API(const jschar *)
4112 JS_GetInternedStringCharsAndLength(JSString *str, size_t *length);
4113
4114 extern JS_PUBLIC_API(const jschar *)
4115 JS_GetStringCharsZ(JSContext *cx, JSString *str);
4116
4117 extern JS_PUBLIC_API(const jschar *)
4118 JS_GetStringCharsZAndLength(JSContext *cx, JSString *str, size_t *length);
4119
4120 extern JS_PUBLIC_API(JSFlatString *)
4121 JS_FlattenString(JSContext *cx, JSString *str);
4122
4123 extern JS_PUBLIC_API(const jschar *)
4124 JS_GetFlatStringChars(JSFlatString *str);
4125
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 }
4132
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 }
4139
4140 static MOZ_ALWAYS_INLINE JSString *
4141 JS_FORGET_STRING_FLATNESS(JSFlatString *fstr)
4142 {
4143 return (JSString *)fstr;
4144 }
4145
4146 /*
4147 * Additional APIs that avoid fallibility when given a flat string.
4148 */
4149
4150 extern JS_PUBLIC_API(bool)
4151 JS_FlatStringEqualsAscii(JSFlatString *str, const char *asciiBytes);
4152
4153 extern JS_PUBLIC_API(size_t)
4154 JS_PutEscapedFlatString(char *buffer, size_t size, JSFlatString *str, char quote);
4155
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);
4164
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);
4171
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);
4188
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);
4195
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);
4201
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);
4209
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);
4220
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 }
4231
4232 JSAutoByteString(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
4233 : mBytes(nullptr)
4234 {
4235 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
4236 }
4237
4238 ~JSAutoByteString() {
4239 js_free(mBytes);
4240 }
4241
4242 /* Take ownership of the given byte array. */
4243 void initBytes(char *bytes) {
4244 JS_ASSERT(!mBytes);
4245 mBytes = bytes;
4246 }
4247
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 }
4254
4255 char *encodeLatin1(js::ExclusiveContext *cx, JSString *str);
4256
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 }
4263
4264 void clear() {
4265 js_free(mBytes);
4266 mBytes = nullptr;
4267 }
4268
4269 char *ptr() const {
4270 return mBytes;
4271 }
4272
4273 bool operator!() const {
4274 return !mBytes;
4275 }
4276
4277 size_t length() const {
4278 if (!mBytes)
4279 return 0;
4280 return strlen(mBytes);
4281 }
4282
4283 private:
4284 char *mBytes;
4285 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
4286
4287 /* Copy and assignment are not supported. */
4288 JSAutoByteString(const JSAutoByteString &another);
4289 JSAutoByteString &operator=(const JSAutoByteString &another);
4290 };
4291
4292 /************************************************************************/
4293 /*
4294 * JSON functions
4295 */
4296 typedef bool (* JSONWriteCallback)(const jschar *buf, uint32_t len, void *data);
4297
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);
4304
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);
4310
4311 JS_PUBLIC_API(bool)
4312 JS_ParseJSONWithReviver(JSContext *cx, const jschar *chars, uint32_t len, JS::HandleValue reviver,
4313 JS::MutableHandleValue vp);
4314
4315 /************************************************************************/
4316
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);
4326
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);
4335
4336 /*
4337 * Reset the default locale to OS defaults.
4338 */
4339 extern JS_PUBLIC_API(void)
4340 JS_ResetDefaultLocale(JSRuntime *rt);
4341
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 };
4352
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);
4359
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);
4366
4367 /************************************************************************/
4368
4369 /*
4370 * Error reporting.
4371 */
4372
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, ...);
4380
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, ...);
4387
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
4393
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, ...);
4400
4401 extern JS_PUBLIC_API(void)
4402 JS_ReportErrorNumberUCArray(JSContext *cx, JSErrorCallback errorCallback,
4403 void *userRef, const unsigned errorNumber,
4404 const jschar **args);
4405
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, ...);
4414
4415 extern JS_PUBLIC_API(bool)
4416 JS_ReportErrorFlagsAndNumber(JSContext *cx, unsigned flags,
4417 JSErrorCallback errorCallback, void *userRef,
4418 const unsigned errorNumber, ...);
4419
4420 extern JS_PUBLIC_API(bool)
4421 JS_ReportErrorFlagsAndNumberUC(JSContext *cx, unsigned flags,
4422 JSErrorCallback errorCallback, void *userRef,
4423 const unsigned errorNumber, ...);
4424
4425 /*
4426 * Complain when out of memory.
4427 */
4428 extern JS_PUBLIC_API(void)
4429 JS_ReportOutOfMemory(JSContext *cx);
4430
4431 /*
4432 * Complain when an allocation size overflows the maximum supported limit.
4433 */
4434 extern JS_PUBLIC_API(void)
4435 JS_ReportAllocationOverflow(JSContext *cx);
4436
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 };
4452
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 */
4460
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
4469
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);
4484
4485 extern JS_PUBLIC_API(JSErrorReporter)
4486 JS_SetErrorReporter(JSContext *cx, JSErrorReporter er);
4487
4488 namespace JS {
4489
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);
4494
4495 /************************************************************************/
4496
4497 /*
4498 * Weak Maps.
4499 */
4500
4501 extern JS_PUBLIC_API(JSObject *)
4502 NewWeakMapObject(JSContext *cx);
4503
4504 extern JS_PUBLIC_API(bool)
4505 IsWeakMapObject(JSObject *obj);
4506
4507 extern JS_PUBLIC_API(bool)
4508 GetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
4509 JS::MutableHandleValue val);
4510
4511 extern JS_PUBLIC_API(bool)
4512 SetWeakMapEntry(JSContext *cx, JS::HandleObject mapObj, JS::HandleObject key,
4513 JS::HandleValue val);
4514
4515 } /* namespace JS */
4516
4517 /*
4518 * Dates.
4519 */
4520
4521 extern JS_PUBLIC_API(JSObject *)
4522 JS_NewDateObject(JSContext *cx, int year, int mon, int mday, int hour, int min, int sec);
4523
4524 extern JS_PUBLIC_API(JSObject *)
4525 JS_NewDateObjectMsec(JSContext *cx, double msec);
4526
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);
4532
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);
4539
4540 /************************************************************************/
4541
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 */
4549
4550 extern JS_PUBLIC_API(JSObject *)
4551 JS_NewRegExpObject(JSContext *cx, JS::HandleObject obj, char *bytes, size_t length,
4552 unsigned flags);
4553
4554 extern JS_PUBLIC_API(JSObject *)
4555 JS_NewUCRegExpObject(JSContext *cx, JS::HandleObject obj, jschar *chars, size_t length,
4556 unsigned flags);
4557
4558 extern JS_PUBLIC_API(void)
4559 JS_SetRegExpInput(JSContext *cx, JS::HandleObject obj, JS::HandleString input,
4560 bool multiline);
4561
4562 extern JS_PUBLIC_API(void)
4563 JS_ClearRegExpStatics(JSContext *cx, JS::HandleObject obj);
4564
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);
4569
4570 /* RegExp interface for clients without a global object. */
4571
4572 extern JS_PUBLIC_API(JSObject *)
4573 JS_NewRegExpObjectNoStatics(JSContext *cx, char *bytes, size_t length, unsigned flags);
4574
4575 extern JS_PUBLIC_API(JSObject *)
4576 JS_NewUCRegExpObjectNoStatics(JSContext *cx, jschar *chars, size_t length, unsigned flags);
4577
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);
4581
4582 extern JS_PUBLIC_API(bool)
4583 JS_ObjectIsRegExp(JSContext *cx, JS::HandleObject obj);
4584
4585 extern JS_PUBLIC_API(unsigned)
4586 JS_GetRegExpFlags(JSContext *cx, JS::HandleObject obj);
4587
4588 extern JS_PUBLIC_API(JSString *)
4589 JS_GetRegExpSource(JSContext *cx, JS::HandleObject obj);
4590
4591 /************************************************************************/
4592
4593 extern JS_PUBLIC_API(bool)
4594 JS_IsExceptionPending(JSContext *cx);
4595
4596 extern JS_PUBLIC_API(bool)
4597 JS_GetPendingException(JSContext *cx, JS::MutableHandleValue vp);
4598
4599 extern JS_PUBLIC_API(void)
4600 JS_SetPendingException(JSContext *cx, JS::HandleValue v);
4601
4602 extern JS_PUBLIC_API(void)
4603 JS_ClearPendingException(JSContext *cx);
4604
4605 extern JS_PUBLIC_API(bool)
4606 JS_ReportPendingException(JSContext *cx);
4607
4608 namespace JS {
4609
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;
4628
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);
4635
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();
4641
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 }
4650
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 };
4658
4659 } /* namespace JS */
4660
4661 /* Deprecated API. Use AutoSaveExceptionState instead. */
4662 extern JS_PUBLIC_API(JSExceptionState *)
4663 JS_SaveExceptionState(JSContext *cx);
4664
4665 extern JS_PUBLIC_API(void)
4666 JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state);
4667
4668 extern JS_PUBLIC_API(void)
4669 JS_DropExceptionState(JSContext *cx, JSExceptionState *state);
4670
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);
4680
4681 /*
4682 * Throws a StopIteration exception on cx.
4683 */
4684 extern JS_PUBLIC_API(bool)
4685 JS_ThrowStopIteration(JSContext *cx);
4686
4687 extern JS_PUBLIC_API(bool)
4688 JS_IsStopIteration(jsval v);
4689
4690 extern JS_PUBLIC_API(intptr_t)
4691 JS_GetCurrentThread();
4692
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 */
4702
4703 extern JS_PUBLIC_API(void)
4704 JS_AbortIfWrongThread(JSRuntime *rt);
4705
4706 /************************************************************************/
4707
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);
4715
4716 /************************************************************************/
4717
4718 #ifdef JS_GC_ZEAL
4719 #define JS_DEFAULT_ZEAL_FREQ 100
4720
4721 extern JS_PUBLIC_API(void)
4722 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
4723
4724 extern JS_PUBLIC_API(void)
4725 JS_ScheduleGC(JSContext *cx, uint32_t count);
4726 #endif
4727
4728 extern JS_PUBLIC_API(void)
4729 JS_SetParallelParsingEnabled(JSRuntime *rt, bool enabled);
4730
4731 extern JS_PUBLIC_API(void)
4732 JS_SetParallelIonCompilationEnabled(JSRuntime *rt, bool enabled);
4733
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")
4740
4741 typedef enum JSJitCompilerOption {
4742 #define JIT_COMPILER_DECLARE(key, str) \
4743 JSJITCOMPILER_ ## key,
4744
4745 JIT_COMPILER_OPTIONS(JIT_COMPILER_DECLARE)
4746 #undef JIT_COMPILER_DECLARE
4747
4748 JSJITCOMPILER_NOT_AN_OPTION
4749 } JSJitCompilerOption;
4750
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);
4755
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);
4761
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);
4769
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);
4775
4776 namespace JS {
4777
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_;
4785
4786 AutoFilename(const AutoFilename &) MOZ_DELETE;
4787 void operator=(const AutoFilename &) MOZ_DELETE;
4788
4789 public:
4790 AutoFilename() : scriptSource_(nullptr) {}
4791 ~AutoFilename() { reset(nullptr); }
4792
4793 const char *get() const;
4794
4795 void reset(void *newScriptSource);
4796 };
4797
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);
4808
4809 extern JS_PUBLIC_API(JSObject *)
4810 GetScriptedCallerGlobal(JSContext *cx);
4811
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);
4826
4827 extern JS_PUBLIC_API(void)
4828 UnhideScriptedCaller(JSContext *cx);
4829
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 }
4843
4844 protected:
4845 JSContext *mContext;
4846 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
4847 };
4848
4849 } /* namespace JS */
4850
4851 /*
4852 * Encode/Decode interpreted scripts and functions to/from memory.
4853 */
4854
4855 extern JS_PUBLIC_API(void *)
4856 JS_EncodeScript(JSContext *cx, JS::HandleScript script, uint32_t *lengthp);
4857
4858 extern JS_PUBLIC_API(void *)
4859 JS_EncodeInterpretedFunction(JSContext *cx, JS::HandleObject funobj, uint32_t *lengthp);
4860
4861 extern JS_PUBLIC_API(JSScript *)
4862 JS_DecodeScript(JSContext *cx, const void *data, uint32_t length, JSPrincipals *originPrincipals);
4863
4864 extern JS_PUBLIC_API(JSObject *)
4865 JS_DecodeInterpretedFunction(JSContext *cx, const void *data, uint32_t length,
4866 JSPrincipals *originPrincipals);
4867
4868 namespace JS {
4869
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);
4885
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);
4908
4909 typedef js::Vector<char, 0, js::SystemAllocPolicy> BuildIdCharVector;
4910
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.
4916
4917 typedef bool
4918 (* BuildIdOp)(BuildIdCharVector *buildId);
4919
4920 struct AsmJSCacheOps
4921 {
4922 OpenAsmJSCacheEntryForReadOp openEntryForRead;
4923 CloseAsmJSCacheEntryForReadOp closeEntryForRead;
4924 OpenAsmJSCacheEntryForWriteOp openEntryForWrite;
4925 CloseAsmJSCacheEntryForWriteOp closeEntryForWrite;
4926 BuildIdOp buildId;
4927 };
4928
4929 extern JS_PUBLIC_API(void)
4930 SetAsmJSCacheOps(JSRuntime *rt, const AsmJSCacheOps *callbacks);
4931
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;
4968
4969 static const uint32_t NOT_ARRAY = UINT32_MAX;
4970
4971 ForOfIterator(const ForOfIterator &) MOZ_DELETE;
4972 ForOfIterator &operator=(const ForOfIterator &) MOZ_DELETE;
4973
4974 public:
4975 ForOfIterator(JSContext *cx) : cx_(cx), iterator(cx_), index(NOT_ARRAY) { }
4976
4977 enum NonIterableBehavior {
4978 ThrowOnNonIterable,
4979 AllowNonIterable
4980 };
4981
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);
4990
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);
4996
4997 /*
4998 * If initialized with throwOnNonCallable = false, check whether
4999 * the value is iterable.
5000 */
5001 bool valueIsIterable() const {
5002 return iterator;
5003 }
5004
5005 private:
5006 inline bool nextFromOptimizedArray(MutableHandleValue val, bool *done);
5007 bool materializeArrayIterator();
5008 };
5009
5010
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 */
5018
5019 typedef void
5020 (* LargeAllocationFailureCallback)();
5021
5022 extern JS_PUBLIC_API(void)
5023 SetLargeAllocationFailureCallback(JSRuntime *rt, LargeAllocationFailureCallback afc);
5024
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 */
5035
5036 typedef void
5037 (* OutOfMemoryCallback)(JSContext *cx);
5038
5039 extern JS_PUBLIC_API(void)
5040 SetOutOfMemoryCallback(JSRuntime *rt, OutOfMemoryCallback cb);
5041
5042 } /* namespace JS */
5043
5044 #endif /* jsapi_h */

mercurial