Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 */ |