|
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 */ |