js/src/jsapi.h

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

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

mercurial