tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

jsfriendapi.h (30719B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef jsfriendapi_h
      8 #define jsfriendapi_h
      9 
     10 #include "jspubtd.h"
     11 
     12 #include "js/CallArgs.h"
     13 #include "js/Class.h"
     14 #include "js/ColumnNumber.h"  // JS::LimitedColumnNumberOneOrigin
     15 #include "js/GCAPI.h"
     16 #include "js/GCVector.h"
     17 #include "js/HeapAPI.h"
     18 #include "js/Object.h"           // JS::GetClass
     19 #include "js/shadow/Function.h"  // JS::shadow::Function
     20 #include "js/shadow/Object.h"    // JS::shadow::Object
     21 #include "js/TypeDecls.h"
     22 
     23 class JSJitInfo;
     24 
     25 /*
     26 * Set a callback used to trace gray roots.
     27 *
     28 * The callback is called after the first slice of GC so the embedding must
     29 * implement appropriate barriers on its gray roots to ensure correctness.
     30 *
     31 * This callback may be called multiple times for different sets of zones. Use
     32 * JS::ZoneIsGrayMarking() to determine whether roots from a particular zone are
     33 * required.
     34 */
     35 extern JS_PUBLIC_API void JS_SetGrayGCRootsTracer(JSContext* cx,
     36                                                  JSGrayRootsTracer traceOp,
     37                                                  void* data);
     38 
     39 extern JS_PUBLIC_API JSObject* JS_FindCompilationScope(JSContext* cx,
     40                                                       JS::HandleObject obj);
     41 
     42 extern JS_PUBLIC_API JSFunction* JS_GetObjectFunction(JSObject* obj);
     43 
     44 /**
     45 * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but
     46 * without invoking the metadata callback on it.  This allows creation of
     47 * internal bookkeeping objects that are guaranteed to not have metadata
     48 * attached to them.
     49 */
     50 extern JS_PUBLIC_API JSObject* JS_NewObjectWithoutMetadata(
     51    JSContext* cx, const JSClass* clasp, JS::Handle<JSObject*> proto);
     52 
     53 extern JS_PUBLIC_API bool JS_NondeterministicGetWeakMapKeys(
     54    JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
     55 
     56 extern JS_PUBLIC_API bool JS_NondeterministicGetWeakSetKeys(
     57    JSContext* cx, JS::HandleObject obj, JS::MutableHandleObject ret);
     58 
     59 // Raw JSScript* because this needs to be callable from a signal handler.
     60 extern JS_PUBLIC_API unsigned JS_PCToLineNumber(
     61    JSScript* script, jsbytecode* pc,
     62    JS::LimitedColumnNumberOneOrigin* columnp = nullptr);
     63 
     64 /**
     65 * Determine whether the given object is backed by a DeadObjectProxy.
     66 *
     67 * Such objects hold no other objects (they have no outgoing reference edges)
     68 * and will throw if you touch them (e.g. by reading/writing a property).
     69 */
     70 extern JS_PUBLIC_API bool JS_IsDeadWrapper(JSObject* obj);
     71 
     72 /**
     73 * Creates a new dead wrapper object in the given scope. To be used when
     74 * attempting to wrap objects from scopes which are already dead.
     75 *
     76 * If origObject is passed, it must be an proxy object, and will be
     77 * used to determine the characteristics of the new dead wrapper.
     78 */
     79 extern JS_PUBLIC_API JSObject* JS_NewDeadWrapper(
     80    JSContext* cx, JSObject* origObject = nullptr);
     81 
     82 /*
     83 * Used by the cycle collector to trace through a shape and all
     84 * cycle-participating data it reaches, using bounded stack space.
     85 */
     86 extern JS_PUBLIC_API void JS_TraceShapeCycleCollectorChildren(
     87    JS::CallbackTracer* trc, JS::GCCellPtr shape);
     88 
     89 extern JS_PUBLIC_API JSPrincipals* JS_GetScriptPrincipals(JSScript* script);
     90 
     91 extern JS_PUBLIC_API bool JS_ScriptHasMutedErrors(JSScript* script);
     92 
     93 extern JS_PUBLIC_API JSObject* JS_CloneObject(JSContext* cx,
     94                                              JS::HandleObject obj,
     95                                              JS::HandleObject proto);
     96 
     97 /**
     98 * Copy the own properties of src to dst in a fast way.  src and dst must both
     99 * be native and must be in the compartment of cx.  They must have the same
    100 * class, the same parent, and the same prototype.  Class reserved slots will
    101 * NOT be copied.
    102 *
    103 * dst must not have any properties on it before this function is called.
    104 *
    105 * src must have been allocated via JS_NewObjectWithoutMetadata so that we can
    106 * be sure it has no metadata that needs copying to dst.  This also means that
    107 * dst needs to have the compartment global as its parent.  This function will
    108 * preserve the existing metadata on dst, if any.
    109 */
    110 extern JS_PUBLIC_API bool JS_InitializePropertiesFromCompatibleNativeObject(
    111    JSContext* cx, JS::HandleObject dst, JS::HandleObject src);
    112 
    113 namespace js {
    114 
    115 JS_PUBLIC_API bool IsArgumentsObject(JS::HandleObject obj);
    116 
    117 JS_PUBLIC_API bool AddRawValueRoot(JSContext* cx, JS::Value* vp,
    118                                   const char* name);
    119 
    120 JS_PUBLIC_API void RemoveRawValueRoot(JSContext* cx, JS::Value* vp);
    121 
    122 }  // namespace js
    123 
    124 namespace JS {
    125 
    126 /**
    127 * Set all of the uninitialized lexicals on an object to undefined. Return
    128 * true if any lexicals were initialized and false otherwise.
    129 * */
    130 extern JS_PUBLIC_API bool ForceLexicalInitialization(JSContext* cx,
    131                                                     HandleObject obj);
    132 
    133 /**
    134 * Whether we are poisoning unused/released data for error detection. Governed
    135 * by the JS_GC_ALLOW_EXTRA_POISONING #ifdef as well as the
    136 * javascript.options.extra_gc_poisoning pref.
    137 */
    138 extern JS_PUBLIC_API bool IsGCPoisoning();
    139 
    140 extern JS_PUBLIC_API JSPrincipals* GetRealmPrincipals(JS::Realm* realm);
    141 
    142 extern JS_PUBLIC_API void SetRealmPrincipals(JS::Realm* realm,
    143                                             JSPrincipals* principals);
    144 
    145 extern JS_PUBLIC_API bool GetIsSecureContext(JS::Realm* realm);
    146 
    147 extern JS_PUBLIC_API bool GetDebuggerObservesWasm(JS::Realm* realm);
    148 
    149 }  // namespace JS
    150 
    151 /**
    152 * Copies all own properties and private fields from |obj| to |target|. Both
    153 * |obj| and |target| must not be cross-compartment wrappers because we have to
    154 * enter their realms.
    155 *
    156 * This function immediately enters a realm, and does not impose any
    157 * restrictions on the realm of |cx|.
    158 */
    159 extern JS_PUBLIC_API bool JS_CopyOwnPropertiesAndPrivateFields(
    160    JSContext* cx, JS::HandleObject target, JS::HandleObject obj);
    161 
    162 extern JS_PUBLIC_API bool JS_WrapPropertyDescriptor(
    163    JSContext* cx, JS::MutableHandle<JS::PropertyDescriptor> desc);
    164 
    165 extern JS_PUBLIC_API bool JS_WrapPropertyDescriptor(
    166    JSContext* cx,
    167    JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc);
    168 
    169 struct JSFunctionSpecWithHelp {
    170  const char* name;
    171  JSNative call;
    172  uint16_t nargs;
    173  uint16_t flags;
    174  const JSJitInfo* jitInfo;
    175  const char* usage;
    176  const char* help;
    177 };
    178 
    179 #define JS_FN_HELP(name, call, nargs, flags, usage, help) \
    180  {name, call, nargs, (flags) | JSPROP_ENUMERATE, nullptr, usage, help}
    181 #define JS_INLINABLE_FN_HELP(name, call, nargs, flags, native, usage, help)    \
    182  {name,  call, nargs, (flags) | JSPROP_ENUMERATE, &js::jit::JitInfo_##native, \
    183   usage, help}
    184 #define JS_FS_HELP_END {nullptr, nullptr, 0, 0, nullptr, nullptr}
    185 
    186 extern JS_PUBLIC_API bool JS_DefineFunctionsWithHelp(
    187    JSContext* cx, JS::HandleObject obj, const JSFunctionSpecWithHelp* fs);
    188 
    189 namespace js {
    190 
    191 /**
    192 * Use the runtime's internal handling of job queues for Promise jobs.
    193 *
    194 * Most embeddings, notably web browsers, will have their own task scheduling
    195 * systems and need to integrate handling of Promise jobs into that, so they
    196 * will want to manage job queues themselves. For basic embeddings such as the
    197 * JS shell that don't have an event loop of their own, it's easier to have
    198 * SpiderMonkey handle job queues internally.
    199 *
    200 * Note that the embedding still has to trigger processing of job queues at
    201 * right time(s), such as after evaluation of a script has run to completion.
    202 */
    203 extern JS_PUBLIC_API bool UseInternalJobQueues(JSContext* cx);
    204 
    205 #ifdef DEBUG
    206 /**
    207 * Given internal job queues are used, return currently queued jobs as an
    208 * array of job objects.
    209 */
    210 extern JS_PUBLIC_API JSObject* GetJobsInInternalJobQueue(JSContext* cx);
    211 #endif
    212 
    213 /**
    214 * Instruct the runtime to stop draining the internal job queue.
    215 *
    216 * Useful if the embedding is in the process of quitting in reaction to a
    217 * builtin being called, or if it wants to resume executing jobs later on.
    218 */
    219 extern JS_PUBLIC_API void StopDrainingJobQueue(JSContext* cx);
    220 
    221 /**
    222 * Instruct the runtime to restart draining the internal job queue after
    223 * stopping it with StopDrainingJobQueue.
    224 */
    225 extern JS_PUBLIC_API void RestartDrainingJobQueue(JSContext* cx);
    226 
    227 extern JS_PUBLIC_API void RunJobs(JSContext* cx);
    228 
    229 extern JS_PUBLIC_API JS::Zone* GetRealmZone(JS::Realm* realm);
    230 
    231 using PreserveWrapperCallback = bool (*)(JSContext*, JS::HandleObject);
    232 using HasReleasedWrapperCallback = bool (*)(JS::HandleObject);
    233 
    234 extern JS_PUBLIC_API bool IsSystemRealm(JS::Realm* realm);
    235 
    236 extern JS_PUBLIC_API bool IsSystemCompartment(JS::Compartment* comp);
    237 
    238 extern JS_PUBLIC_API bool IsSystemZone(JS::Zone* zone);
    239 
    240 struct WeakMapTracer {
    241  JSRuntime* runtime;
    242 
    243  explicit WeakMapTracer(JSRuntime* rt) : runtime(rt) {}
    244 
    245  // Weak map tracer callback, called once for every binding of every
    246  // weak map that was live at the time of the last garbage collection.
    247  //
    248  // m will be nullptr if the weak map is not contained in a JS Object.
    249  //
    250  // The callback should not GC (and will assert in a debug build if it does
    251  // so.)
    252  virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0;
    253 };
    254 
    255 extern JS_PUBLIC_API void TraceWeakMaps(WeakMapTracer* trc);
    256 
    257 extern JS_PUBLIC_API bool AreGCGrayBitsValid(JSRuntime* rt);
    258 
    259 extern JS_PUBLIC_API bool ZoneGlobalsAreAllGray(JS::Zone* zone);
    260 
    261 extern JS_PUBLIC_API bool IsCompartmentZoneSweepingOrCompacting(
    262    JS::Compartment* comp);
    263 
    264 using IterateGCThingCallback = void (*)(void*, JS::GCCellPtr,
    265                                        const JS::AutoRequireNoGC&);
    266 
    267 extern JS_PUBLIC_API void TraceGrayWrapperTargets(JSTracer* trc,
    268                                                  JS::Zone* zone);
    269 
    270 /**
    271 * Invoke cellCallback on every gray JSObject in the given zone.
    272 */
    273 extern JS_PUBLIC_API void IterateGrayObjects(
    274    JS::Zone* zone, IterateGCThingCallback cellCallback, void* data);
    275 
    276 #if defined(JS_GC_ZEAL) || defined(DEBUG)
    277 // Trace the heap and check there are no black to gray edges. These are
    278 // not allowed since the cycle collector could throw away the gray thing and
    279 // leave a dangling pointer.
    280 //
    281 // This doesn't trace weak maps as these are handled separately.
    282 extern JS_PUBLIC_API bool CheckGrayMarkingState(JSRuntime* rt);
    283 #endif
    284 
    285 // Note: this returns nullptr iff |zone| is the atoms zone.
    286 extern JS_PUBLIC_API JS::Realm* GetAnyRealmInZone(JS::Zone* zone);
    287 
    288 // Returns the first realm's global in a compartment. Note: this is not
    289 // guaranteed to always be the same realm because individual realms can be
    290 // collected by the GC.
    291 extern JS_PUBLIC_API JSObject* GetFirstGlobalInCompartment(
    292    JS::Compartment* comp);
    293 
    294 // Returns true if the compartment contains a global object and this global is
    295 // not being collected.
    296 extern JS_PUBLIC_API bool CompartmentHasLiveGlobal(JS::Compartment* comp);
    297 
    298 // Returns true if this compartment can be shared across multiple Realms.  Used
    299 // when we're looking for an existing compartment to place a new Realm in.
    300 extern JS_PUBLIC_API bool IsSharableCompartment(JS::Compartment* comp);
    301 
    302 // This is equal to |&JSObject::class_|.  Use it in places where you don't want
    303 // to #include vm/JSObject.h.
    304 extern JS_PUBLIC_DATA const JSClass* const ObjectClassPtr;
    305 
    306 JS_PUBLIC_API const JSClass* ProtoKeyToClass(JSProtoKey key);
    307 
    308 // Returns the key for the class inherited by a given standard class (that
    309 // is to say, the prototype of this standard class's prototype).
    310 //
    311 // You must be sure that this corresponds to a standard class with a cached
    312 // JSProtoKey before calling this function. In general |key| will match the
    313 // cached proto key, except in cases where multiple JSProtoKeys share a
    314 // JSClass.
    315 inline JSProtoKey InheritanceProtoKeyForStandardClass(JSProtoKey key) {
    316  // [Object] has nothing to inherit from.
    317  if (key == JSProto_Object) {
    318    return JSProto_Null;
    319  }
    320 
    321  // If we're ClassSpec defined return the proto key from that
    322  if (ProtoKeyToClass(key)->specDefined()) {
    323    return ProtoKeyToClass(key)->specInheritanceProtoKey();
    324  }
    325 
    326  // Otherwise, we inherit [Object].
    327  return JSProto_Object;
    328 }
    329 
    330 JS_PUBLIC_API bool ShouldIgnorePropertyDefinition(JSContext* cx, JSProtoKey key,
    331                                                  jsid id);
    332 
    333 JS_PUBLIC_API bool IsFunctionObject(JSObject* obj);
    334 
    335 JS_PUBLIC_API bool UninlinedIsCrossCompartmentWrapper(const JSObject* obj);
    336 
    337 // CrossCompartmentWrappers are shared by all realms within the compartment, so
    338 // getting a wrapper's realm usually doesn't make sense.
    339 static MOZ_ALWAYS_INLINE JS::Realm* GetNonCCWObjectRealm(JSObject* obj) {
    340  MOZ_ASSERT(!js::UninlinedIsCrossCompartmentWrapper(obj));
    341  return reinterpret_cast<JS::shadow::Object*>(obj)->shape->base->realm;
    342 }
    343 
    344 JS_PUBLIC_API void AssertSameCompartment(JSContext* cx, JSObject* obj);
    345 
    346 JS_PUBLIC_API void AssertSameCompartment(JSContext* cx, JS::HandleValue v);
    347 
    348 #ifdef JS_DEBUG
    349 JS_PUBLIC_API void AssertSameCompartment(JSObject* objA, JSObject* objB);
    350 #else
    351 inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {}
    352 #endif
    353 
    354 JS_PUBLIC_API void NotifyAnimationActivity(JSObject* obj);
    355 
    356 JS_PUBLIC_API JSFunction* DefineFunctionWithReserved(
    357    JSContext* cx, JSObject* obj, const char* name, JSNative call,
    358    unsigned nargs, unsigned attrs);
    359 
    360 JS_PUBLIC_API JSFunction* NewFunctionWithReserved(JSContext* cx, JSNative call,
    361                                                  unsigned nargs,
    362                                                  unsigned flags,
    363                                                  const char* name);
    364 
    365 JS_PUBLIC_API JSFunction* NewFunctionByIdWithReserved(JSContext* cx,
    366                                                      JSNative native,
    367                                                      unsigned nargs,
    368                                                      unsigned flags, jsid id);
    369 
    370 JS_PUBLIC_API JSFunction* NewFunctionByIdWithReservedAndProto(
    371    JSContext* cx, JSNative native, JS::Handle<JSObject*> proto, unsigned nargs,
    372    unsigned flags, jsid id);
    373 
    374 /**
    375 * Get or set function's reserved slot value.
    376 * `fun` should be a function created with `*WithReserved` API above.
    377 * Such functions have 2 reserved slots, and `which` can be either 0 or 1.
    378 */
    379 JS_PUBLIC_API const JS::Value& GetFunctionNativeReserved(JSObject* fun,
    380                                                         size_t which);
    381 
    382 JS_PUBLIC_API void SetFunctionNativeReserved(JSObject* fun, size_t which,
    383                                             const JS::Value& val);
    384 
    385 JS_PUBLIC_API bool FunctionHasNativeReserved(JSObject* fun);
    386 
    387 JS_PUBLIC_API bool GetObjectProto(JSContext* cx, JS::HandleObject obj,
    388                                  JS::MutableHandleObject proto);
    389 
    390 extern JS_PUBLIC_API JSObject* GetStaticPrototype(JSObject* obj);
    391 
    392 JS_PUBLIC_API bool GetRealmOriginalEval(JSContext* cx,
    393                                        JS::MutableHandleObject eval);
    394 
    395 /**
    396 * Add some or all property keys of obj to the id vector *props.
    397 *
    398 * The flags parameter controls which property keys are added. Pass a
    399 * combination of the following bits:
    400 *
    401 *     JSITER_OWNONLY - Don't also search the prototype chain; only consider
    402 *       obj's own properties.
    403 *
    404 *     JSITER_HIDDEN - Include nonenumerable properties.
    405 *
    406 *     JSITER_SYMBOLS - Include property keys that are symbols. The default
    407 *       behavior is to filter out symbols.
    408 *
    409 *     JSITER_SYMBOLSONLY - Exclude non-symbol property keys.
    410 *
    411 * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or
    412 * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass
    413 * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get
    414 * results that match the output of Reflect.ownKeys.
    415 */
    416 JS_PUBLIC_API bool GetPropertyKeys(JSContext* cx, JS::HandleObject obj,
    417                                   unsigned flags,
    418                                   JS::MutableHandleIdVector props);
    419 
    420 JS_PUBLIC_API bool AppendUnique(JSContext* cx, JS::MutableHandleIdVector base,
    421                                JS::HandleIdVector others);
    422 
    423 /**
    424 * Direct embedder access for retrieving a copy of all entries in a Set or Map
    425 * object.
    426 */
    427 JS_PUBLIC_API bool GetSetObjectKeys(
    428    JSContext* cx, JS::HandleObject obj,
    429    JS::MutableHandle<JS::GCVector<JS::Value>> keys);
    430 
    431 JS_PUBLIC_API bool GetMapObjectKeysAndValuesInterleaved(
    432    JSContext* cx, JS::HandleObject obj,
    433    JS::MutableHandle<JS::GCVector<JS::Value>> entries);
    434 
    435 /**
    436 * Determine whether the given string is an array index in the sense of
    437 * <https://tc39.github.io/ecma262/#array-index>.
    438 *
    439 * If it isn't, returns false.
    440 *
    441 * If it is, returns true and outputs the index in *indexp.
    442 */
    443 JS_PUBLIC_API bool StringIsArrayIndex(const JSLinearString* str,
    444                                      uint32_t* indexp);
    445 
    446 /**
    447 * Overload of StringIsArrayIndex taking a (char16_t*,length) pair. Behaves
    448 * the same as the JSLinearString version.
    449 */
    450 JS_PUBLIC_API bool StringIsArrayIndex(const char16_t* str, uint32_t length,
    451                                      uint32_t* indexp);
    452 
    453 JS_PUBLIC_API void SetPreserveWrapperCallbacks(
    454    JSContext* cx, PreserveWrapperCallback preserveWrapper,
    455    HasReleasedWrapperCallback hasReleasedWrapper);
    456 
    457 JS_PUBLIC_API void CommitPendingWrapperPreservations(JSContext* cx);
    458 
    459 JS_PUBLIC_API bool IsObjectInContextCompartment(JSObject* obj,
    460                                                const JSContext* cx);
    461 
    462 /*
    463 * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
    464 */
    465 /* 0x1 is no longer used */
    466 /* 0x2 is no longer used */
    467 #define JSITER_PRIVATE 0x4      /* Include private names in iteration */
    468 #define JSITER_OWNONLY 0x8      /* iterate over obj's own properties only */
    469 #define JSITER_HIDDEN 0x10      /* also enumerate non-enumerable properties */
    470 #define JSITER_SYMBOLS 0x20     /* also include symbol property keys */
    471 #define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
    472 #define JSITER_FORAWAITOF 0x80  /* for-await-of */
    473 
    474 using DOMInstanceClassHasProtoAtDepth = bool (*)(const JSClass*, uint32_t,
    475                                                 uint32_t);
    476 using DOMInstanceClassIsError = bool (*)(const JSClass*);
    477 
    478 using DOMExtractExceptionInfo = bool (*)(JSContext*, JS::HandleObject, bool*,
    479                                         JS::MutableHandle<JSString*>,
    480                                         uint32_t*, uint32_t*,
    481                                         JS::MutableHandle<JSString*>);
    482 
    483 struct JSDOMCallbacks {
    484  DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto;
    485  DOMInstanceClassIsError instanceClassIsError;
    486  DOMExtractExceptionInfo extractExceptionInfo;
    487 };
    488 using DOMCallbacks = struct JSDOMCallbacks;
    489 
    490 extern JS_PUBLIC_API void SetDOMCallbacks(JSContext* cx,
    491                                          const DOMCallbacks* callbacks);
    492 
    493 extern JS_PUBLIC_API const DOMCallbacks* GetDOMCallbacks(JSContext* cx);
    494 
    495 extern JS_PUBLIC_API JSObject* GetTestingFunctions(JSContext* cx);
    496 
    497 /* Implemented in jsexn.cpp. */
    498 
    499 /**
    500 * Get an error type name from a JSExnType constant.
    501 * Returns nullptr for invalid arguments and JSEXN_INTERNALERR
    502 */
    503 extern JS_PUBLIC_API JSLinearString* GetErrorTypeName(JSContext* cx,
    504                                                      int16_t exnType);
    505 
    506 /* Implemented in CrossCompartmentWrapper.cpp. */
    507 enum NukeReferencesToWindow { NukeWindowReferences, DontNukeWindowReferences };
    508 
    509 enum NukeReferencesFromTarget {
    510  NukeAllReferences,
    511  NukeIncomingReferences,
    512 };
    513 
    514 /*
    515 * These filters are designed to be ephemeral stack classes, and thus don't
    516 * do any rooting or holding of their members.
    517 */
    518 struct CompartmentFilter {
    519  virtual bool match(JS::Compartment* c) const = 0;
    520 };
    521 
    522 struct AllCompartments : public CompartmentFilter {
    523  virtual bool match(JS::Compartment* c) const override { return true; }
    524 };
    525 
    526 struct SingleCompartment : public CompartmentFilter {
    527  JS::Compartment* ours;
    528  explicit SingleCompartment(JS::Compartment* c) : ours(c) {}
    529  virtual bool match(JS::Compartment* c) const override { return c == ours; }
    530 };
    531 
    532 extern JS_PUBLIC_API bool NukeCrossCompartmentWrappers(
    533    JSContext* cx, const CompartmentFilter& sourceFilter, JS::Realm* target,
    534    NukeReferencesToWindow nukeReferencesToWindow,
    535    NukeReferencesFromTarget nukeReferencesFromTarget);
    536 
    537 extern JS_PUBLIC_API bool AllowNewWrapper(JS::Compartment* target,
    538                                          JSObject* obj);
    539 
    540 extern JS_PUBLIC_API bool NukedObjectRealm(JSObject* obj);
    541 
    542 /* Implemented in jsdate.cpp. */
    543 
    544 /** Detect whether the internal date value is NaN. */
    545 extern JS_PUBLIC_API bool DateIsValid(JSContext* cx, JS::HandleObject obj,
    546                                      bool* isValid);
    547 
    548 extern JS_PUBLIC_API bool DateGetMsecSinceEpoch(JSContext* cx,
    549                                                JS::HandleObject obj,
    550                                                double* msecSinceEpoch);
    551 
    552 } /* namespace js */
    553 
    554 namespace js {
    555 
    556 /* Implemented in vm/StructuredClone.cpp. */
    557 extern JS_PUBLIC_API uint64_t GetSCOffset(JSStructuredCloneWriter* writer);
    558 
    559 }  // namespace js
    560 
    561 namespace js {
    562 
    563 /* Statically asserted in FunctionFlags.cpp. */
    564 static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0060;
    565 
    566 }  // namespace js
    567 
    568 static MOZ_ALWAYS_INLINE const JSJitInfo* FUNCTION_VALUE_TO_JITINFO(
    569    const JS::Value& v) {
    570  JSObject* obj = &v.toObject();
    571  MOZ_ASSERT(JS::GetClass(obj)->isJSFunction());
    572 
    573  auto* fun = reinterpret_cast<JS::shadow::Function*>(obj);
    574  MOZ_ASSERT(!(fun->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS),
    575             "Unexpected non-native function");
    576 
    577  return static_cast<const JSJitInfo*>(fun->jitInfoOrScript());
    578 }
    579 
    580 static MOZ_ALWAYS_INLINE void SET_JITINFO(JSFunction* func,
    581                                          const JSJitInfo* info) {
    582  auto* fun = reinterpret_cast<JS::shadow::Function*>(func);
    583  MOZ_ASSERT(!(fun->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS));
    584 
    585  fun->setJitInfoOrScript(const_cast<JSJitInfo*>(info));
    586 }
    587 
    588 static_assert(sizeof(jsid) == sizeof(void*));
    589 
    590 namespace js {
    591 
    592 static MOZ_ALWAYS_INLINE JS::Value IdToValue(jsid id) {
    593  if (id.isString()) {
    594    return JS::StringValue(id.toString());
    595  }
    596  if (id.isInt()) {
    597    return JS::Int32Value(id.toInt());
    598  }
    599  if (id.isSymbol()) {
    600    return JS::SymbolValue(id.toSymbol());
    601  }
    602  MOZ_ASSERT(id.isVoid());
    603  return JS::UndefinedValue();
    604 }
    605 
    606 /**
    607 * PrepareScriptEnvironmentAndInvoke asserts the embedder has registered a
    608 * ScriptEnvironmentPreparer and then it calls the preparer's 'invoke' method
    609 * with the given |closure|, with the assumption that the preparer will set up
    610 * any state necessary to run script in |global|, invoke |closure| with a valid
    611 * JSContext*, report any exceptions thrown from the closure, and return.
    612 *
    613 * PrepareScriptEnvironmentAndInvoke will report any exceptions that are thrown
    614 * by the closure.  Consumers who want to propagate back whether the closure
    615 * succeeded should do so via members of the closure itself.
    616 */
    617 
    618 struct ScriptEnvironmentPreparer {
    619  struct Closure {
    620    virtual bool operator()(JSContext* cx) = 0;
    621  };
    622 
    623  virtual void invoke(JS::HandleObject global, Closure& closure) = 0;
    624 };
    625 
    626 extern JS_PUBLIC_API void PrepareScriptEnvironmentAndInvoke(
    627    JSContext* cx, JS::HandleObject global,
    628    ScriptEnvironmentPreparer::Closure& closure);
    629 
    630 JS_PUBLIC_API void SetScriptEnvironmentPreparer(
    631    JSContext* cx, ScriptEnvironmentPreparer* preparer);
    632 
    633 // Abstract base class for objects that build allocation metadata for JavaScript
    634 // values.
    635 struct AllocationMetadataBuilder {
    636  AllocationMetadataBuilder() = default;
    637 
    638  // Return a metadata object for the newly constructed object |obj|, or
    639  // nullptr if there's no metadata to attach.
    640  //
    641  // Implementations should treat all errors as fatal; there is no way to
    642  // report errors from this callback. In particular, the caller provides an
    643  // oomUnsafe for overriding implementations to use.
    644  virtual JSObject* build(JSContext* cx, JS::HandleObject obj,
    645                          AutoEnterOOMUnsafeRegion& oomUnsafe) const {
    646    return nullptr;
    647  }
    648 };
    649 
    650 /**
    651 * Specify a callback to invoke when creating each JS object in the current
    652 * compartment, which may return a metadata object to associate with the
    653 * object.
    654 */
    655 JS_PUBLIC_API void SetAllocationMetadataBuilder(
    656    JSContext* cx, const AllocationMetadataBuilder* callback);
    657 
    658 /** Get the metadata associated with an object. */
    659 JS_PUBLIC_API JSObject* GetAllocationMetadata(JSObject* obj);
    660 
    661 JS_PUBLIC_API bool GetElementsWithAdder(JSContext* cx, JS::HandleObject obj,
    662                                        JS::HandleObject receiver,
    663                                        uint32_t begin, uint32_t end,
    664                                        js::ElementAdder* adder);
    665 
    666 JS_PUBLIC_API bool ForwardToNative(JSContext* cx, JSNative native,
    667                                   const JS::CallArgs& args);
    668 
    669 /**
    670 * Helper function for HTMLDocument and HTMLFormElement.
    671 *
    672 * These are the only two interfaces that have [OverrideBuiltins], a named
    673 * getter, and no named setter. They're implemented as proxies with a custom
    674 * getOwnPropertyDescriptor() method. Unfortunately, overriding
    675 * getOwnPropertyDescriptor() automatically affects the behavior of set(),
    676 * which normally is just common sense but is *not* desired for these two
    677 * interfaces.
    678 *
    679 * The fix is for these two interfaces to override set() to ignore the
    680 * getOwnPropertyDescriptor() override.
    681 *
    682 * SetPropertyIgnoringNamedGetter is exposed to make it easier to override
    683 * set() in this way.  It carries out all the steps of BaseProxyHandler::set()
    684 * except the initial getOwnPropertyDescriptor() call.  The caller must supply
    685 * that descriptor as the 'ownDesc' parameter.
    686 *
    687 * Implemented in proxy/BaseProxyHandler.cpp.
    688 */
    689 JS_PUBLIC_API bool SetPropertyIgnoringNamedGetter(
    690    JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
    691    JS::HandleValue receiver,
    692    JS::Handle<mozilla::Maybe<JS::PropertyDescriptor>> ownDesc,
    693    JS::ObjectOpResult& result);
    694 
    695 // This function is for one specific use case, please don't use this for
    696 // anything else!
    697 extern JS_PUBLIC_API bool ExecuteInFrameScriptEnvironment(
    698    JSContext* cx, JS::HandleObject obj, JS::HandleScript script,
    699    JS::MutableHandleObject scope);
    700 
    701 extern JS_PUBLIC_API bool IsSavedFrame(JSObject* obj);
    702 
    703 // Matches the condition in js/src/jit/ProcessExecutableMemory.cpp
    704 #if defined(XP_WIN)
    705 // Parameters use void* types to avoid #including windows.h. The return value of
    706 // this function is returned from the exception handler.
    707 using JitExceptionHandler = long (*)(void* exceptionRecord,  // PEXECTION_RECORD
    708                                     void* context);         // PCONTEXT
    709 
    710 /**
    711 * Windows uses "structured exception handling" to handle faults. When a fault
    712 * occurs, the stack is searched for a handler (similar to C++ exception
    713 * handling). If the search does not find a handler, the "unhandled exception
    714 * filter" is called. Breakpad uses the unhandled exception filter to do crash
    715 * reporting. Unfortunately, on Win64, JIT code on the stack completely throws
    716 * off this unwinding process and prevents the unhandled exception filter from
    717 * being called. The reason is that Win64 requires unwind information be
    718 * registered for all code regions and JIT code has none. While it is possible
    719 * to register full unwind information for JIT code, this is a lot of work (one
    720 * has to be able to recover the frame pointer at any PC) so instead we register
    721 * a handler for all JIT code that simply calls breakpad's unhandled exception
    722 * filter (which will perform crash reporting and then terminate the process).
    723 * This would be wrong if there was an outer __try block that expected to handle
    724 * the fault, but this is not generally allowed.
    725 *
    726 * Gecko must call SetJitExceptionFilter before any JIT code is compiled and
    727 * only once per process.
    728 */
    729 extern JS_PUBLIC_API void SetJitExceptionHandler(JitExceptionHandler handler);
    730 #endif
    731 
    732 extern JS_PUBLIC_API bool ReportIsNotFunction(JSContext* cx, JS::HandleValue v);
    733 
    734 class MOZ_STACK_CLASS JS_PUBLIC_API AutoAssertNoContentJS {
    735 public:
    736  explicit AutoAssertNoContentJS(JSContext* cx);
    737  ~AutoAssertNoContentJS();
    738 
    739 private:
    740  JSContext* context_;
    741  bool prevAllowContentJS_;
    742 };
    743 
    744 /**
    745 * This function reports memory used by a zone in bytes, this includes:
    746 *  * The size of this JS GC zone.
    747 *  * Malloc memory referred to from this zone.
    748 *  * JIT memory for this zone.
    749 *
    750 * Note that malloc memory referred to from this zone can include
    751 * SharedArrayBuffers which may also be referred to from other zones. Adding the
    752 * memory usage of multiple zones may lead to an over-estimate.
    753 */
    754 extern JS_PUBLIC_API uint64_t GetMemoryUsageForZone(JS::Zone* zone);
    755 
    756 enum class MemoryUse : uint8_t;
    757 
    758 namespace gc {
    759 
    760 struct SharedMemoryUse {
    761  explicit SharedMemoryUse(MemoryUse use) : count(0), nbytes(0) {
    762 #ifdef DEBUG
    763    this->use = use;
    764 #endif
    765  }
    766 
    767  size_t count;
    768  size_t nbytes;
    769 #ifdef DEBUG
    770  MemoryUse use;
    771 #endif
    772 };
    773 
    774 // A map which tracks shared memory uses (shared in the sense that an allocation
    775 // can be referenced by more than one GC thing in a zone). This allows us to
    776 // only account for the memory once.
    777 using SharedMemoryMap =
    778    HashMap<void*, SharedMemoryUse, DefaultHasher<void*>, SystemAllocPolicy>;
    779 
    780 } /* namespace gc */
    781 
    782 extern JS_PUBLIC_API const gc::SharedMemoryMap& GetSharedMemoryUsageForZone(
    783    JS::Zone* zone);
    784 
    785 // Get the total amount of GC heap memory used by the runtime, including malloc
    786 // memory.
    787 extern JS_PUBLIC_API uint64_t GetGCHeapUsage(JSContext* cx);
    788 
    789 class JS_PUBLIC_API CompartmentTransplantCallback {
    790 public:
    791  virtual JSObject* getObjectToTransplant(JS::Compartment* compartment) = 0;
    792 };
    793 
    794 // Gather a set of remote window proxies by calling the callback on every
    795 // compartment, then transform them into cross-compartment wrappers to newTarget
    796 // via brain transplants. If there's a proxy in newTarget's compartment, it will
    797 // get swapped with newTarget, and the value of newTarget will be updated. If
    798 // the callback returns null for a compartment, no cross-compartment wrapper
    799 // will be created for that compartment. Any non-null values it returns must be
    800 // DOM remote proxies from the compartment that was passed in.
    801 extern JS_PUBLIC_API void RemapRemoteWindowProxies(
    802    JSContext* cx, CompartmentTransplantCallback* callback,
    803    JS::MutableHandleObject newTarget);
    804 
    805 extern JS_PUBLIC_API JS::Zone* GetObjectZoneFromAnyThread(const JSObject* obj);
    806 
    807 } /* namespace js */
    808 
    809 #endif /* jsfriendapi_h */