tor-browser

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

Runtime.h (41103B)


      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 vm_Runtime_h
      8 #define vm_Runtime_h
      9 
     10 #include "mozilla/Assertions.h"  // MOZ_ASSERT
     11 #include "mozilla/Atomics.h"
     12 #include "mozilla/Attributes.h"
     13 #include "mozilla/DoublyLinkedList.h"
     14 #include "mozilla/LinkedList.h"
     15 #include "mozilla/Maybe.h"
     16 #include "mozilla/MemoryReporting.h"
     17 #include "mozilla/TimeStamp.h"
     18 #include "mozilla/XorShift128PlusRNG.h"
     19 
     20 #include <algorithm>
     21 #include <utility>
     22 
     23 #ifdef JS_HAS_INTL_API
     24 #  include "builtin/intl/SharedIntlData.h"
     25 #endif
     26 #include "frontend/ScriptIndex.h"
     27 #include "gc/GCRuntime.h"
     28 #include "js/AllocationRecording.h"
     29 #include "js/BuildId.h"  // JS::BuildIdOp
     30 #include "js/Context.h"
     31 #include "js/DOMEventDispatch.h"
     32 #include "js/experimental/CTypes.h"     // JS::CTypesActivityCallback
     33 #include "js/friend/StackLimits.h"      // js::ReportOverRecursed
     34 #include "js/friend/UsageStatistics.h"  // JSAccumulateTelemetryDataCallback
     35 #include "js/GCVector.h"
     36 #include "js/HashTable.h"
     37 #include "js/Initialization.h"
     38 #include "js/MemoryCallbacks.h"
     39 #include "js/Modules.h"  // JS::Module{DynamicImport,Metadata,Resolve}Hook
     40 #include "js/ScriptPrivate.h"
     41 #include "js/shadow/Zone.h"
     42 #include "js/ShadowRealmCallbacks.h"
     43 #include "js/Stack.h"
     44 #include "js/StreamConsumer.h"
     45 #include "js/Symbol.h"
     46 #include "js/UniquePtr.h"
     47 #include "js/Utility.h"
     48 #include "js/WaitCallbacks.h"
     49 #include "js/Warnings.h"  // JS::WarningReporter
     50 #include "js/Zone.h"
     51 #include "vm/Caches.h"  // js::RuntimeCaches
     52 #include "vm/CodeCoverage.h"
     53 #include "vm/GeckoProfiler.h"
     54 #include "vm/InvalidatingFuse.h"
     55 #include "vm/JSScript.h"
     56 #include "vm/Logging.h"
     57 #include "vm/OffThreadPromiseRuntimeState.h"  // js::OffThreadPromiseRuntimeState
     58 #include "vm/RuntimeFuses.h"
     59 #include "vm/SharedScriptDataTableHolder.h"  // js::SharedScriptDataTableHolder
     60 #include "vm/Stack.h"
     61 #include "wasm/WasmTypeDecls.h"
     62 
     63 struct JSAtomState;
     64 struct JSClass;
     65 struct JSErrorInterceptor;
     66 struct JSWrapObjectCallbacks;
     67 
     68 namespace js {
     69 
     70 class AutoAssertNoContentJS;
     71 class Debugger;
     72 class EnterDebuggeeNoExecute;
     73 class FrontendContext;
     74 class PlainObject;
     75 class StaticStrings;
     76 
     77 }  // namespace js
     78 
     79 struct DtoaState;
     80 struct JSLocaleCallbacks;
     81 
     82 #ifdef JS_SIMULATOR_ARM64
     83 namespace vixl {
     84 class Simulator;
     85 }
     86 #endif
     87 
     88 namespace js {
     89 
     90 extern MOZ_COLD void ReportOutOfMemory(JSContext* cx);
     91 extern MOZ_COLD void ReportAllocationOverflow(JSContext* maybecx);
     92 extern MOZ_COLD void ReportAllocationOverflow(FrontendContext* fc);
     93 extern MOZ_COLD void ReportOversizedAllocation(JSContext* cx,
     94                                               const unsigned errorNumber);
     95 
     96 class Activation;
     97 class ActivationIterator;
     98 class Shape;
     99 class SourceHook;
    100 
    101 namespace jit {
    102 class JitRuntime;
    103 class JitActivation;
    104 struct PcScriptCache;
    105 class CompileRuntime;
    106 
    107 #ifdef JS_SIMULATOR_ARM64
    108 using vixl::Simulator;
    109 #elif defined(JS_SIMULATOR)
    110 class Simulator;
    111 #endif
    112 }  // namespace jit
    113 
    114 namespace frontend {
    115 struct CompilationInput;
    116 struct CompilationStencil;
    117 }  // namespace frontend
    118 
    119 // [SMDOC] JS Engine Threading
    120 //
    121 // Threads interacting with a runtime are divided into two categories:
    122 //
    123 // - The main thread is capable of running JS. There's at most one main thread
    124 //   per runtime.
    125 //
    126 // - Helper threads do not run JS, and are controlled or triggered by activity
    127 //   on the main thread (or main threads, since all runtimes in a process share
    128 //   helper threads). Helper threads may have exclusive access to zones created
    129 //   for them, for parsing and similar tasks, but their activities do not cause
    130 //   observable changes in script behaviors. Activity on helper threads may be
    131 //   referred to as happening 'off thread' or on a background thread in some
    132 //   parts of the VM.
    133 
    134 } /* namespace js */
    135 
    136 namespace JS {
    137 struct RuntimeSizes;
    138 }  // namespace JS
    139 
    140 namespace js {
    141 
    142 /*
    143 * Storage for well-known symbols. It's a separate struct from the Runtime so
    144 * that it can be shared across multiple runtimes. As in JSAtomState, each
    145 * field is a smart pointer that's immutable once initialized.
    146 * `rt->wellKnownSymbols->iterator` is convertible to Handle<Symbol*>.
    147 *
    148 * Well-known symbols are never GC'd. The description() of each well-known
    149 * symbol is a permanent atom.
    150 */
    151 struct WellKnownSymbols {
    152 #define DECLARE_SYMBOL(name) ImmutableTenuredPtr<JS::Symbol*> name;
    153  JS_FOR_EACH_WELL_KNOWN_SYMBOL(DECLARE_SYMBOL)
    154 #undef DECLARE_SYMBOL
    155 
    156  const ImmutableTenuredPtr<JS::Symbol*>& get(size_t u) const {
    157    MOZ_ASSERT(u < JS::WellKnownSymbolLimit);
    158    const ImmutableTenuredPtr<JS::Symbol*>* symbols =
    159        reinterpret_cast<const ImmutableTenuredPtr<JS::Symbol*>*>(this);
    160    return symbols[u];
    161  }
    162 
    163  const ImmutableTenuredPtr<JS::Symbol*>& get(JS::SymbolCode code) const {
    164    return get(size_t(code));
    165  }
    166 
    167  WellKnownSymbols() = default;
    168  WellKnownSymbols(const WellKnownSymbols&) = delete;
    169  WellKnownSymbols& operator=(const WellKnownSymbols&) = delete;
    170 };
    171 
    172 // There are several coarse locks in the enum below. These may be either
    173 // per-runtime or per-process. When acquiring more than one of these locks,
    174 // the acquisition must be done in the order below to avoid deadlocks.
    175 enum RuntimeLock { HelperThreadStateLock, GCLock };
    176 
    177 inline bool CanUseExtraThreads() {
    178  extern bool gCanUseExtraThreads;
    179  return gCanUseExtraThreads;
    180 }
    181 
    182 void DisableExtraThreads();
    183 
    184 using ScriptAndCountsVector = GCVector<ScriptAndCounts, 0, SystemAllocPolicy>;
    185 
    186 class AutoLockScriptData;
    187 
    188 // Self-hosted lazy functions do not maintain a BaseScript as we can clone from
    189 // the copy in the self-hosting zone. To allow these functions to be called by
    190 // the JITs, we need a minimal script object. There is one instance per runtime.
    191 struct SelfHostedLazyScript {
    192  SelfHostedLazyScript() = default;
    193 
    194  // Pointer to interpreter trampoline. This field is stored at same location as
    195  // in BaseScript::jitCodeRaw_.
    196  uint8_t* jitCodeRaw_ = nullptr;
    197 
    198  // Warm-up count of zero. This field is stored at the same offset as
    199  // BaseScript::warmUpData_.
    200  ScriptWarmUpData warmUpData_ = {};
    201 
    202  static constexpr size_t offsetOfJitCodeRaw() {
    203    return offsetof(SelfHostedLazyScript, jitCodeRaw_);
    204  }
    205  static constexpr size_t offsetOfWarmUpData() {
    206    return offsetof(SelfHostedLazyScript, warmUpData_);
    207  }
    208 };
    209 
    210 // An interface for reporting telemetry from within SpiderMonkey. Reporting data
    211 // to this interface will forward it to the embedding if a telemetry callback
    212 // was registered. It is the embedding's responsibility to store and/or combine
    213 // repeated samples for each metric.
    214 class Metrics {
    215 private:
    216  JSRuntime* rt_;
    217 
    218 public:
    219  explicit Metrics(JSRuntime* rt) : rt_(rt) {}
    220 
    221  // Records a TimeDuration metric. These are converted to integers when being
    222  // recorded so choose an appropriate scale. In the future these will be Glean
    223  // Timing Distribution metrics.
    224  struct TimeDuration_S {
    225    using SourceType = mozilla::TimeDuration;
    226    static uint32_t convert(SourceType td) { return uint32_t(td.ToSeconds()); }
    227  };
    228  struct TimeDuration_MS {
    229    using SourceType = mozilla::TimeDuration;
    230    static uint32_t convert(SourceType td) {
    231      return uint32_t(td.ToMilliseconds());
    232    }
    233  };
    234  struct TimeDuration_US {
    235    using SourceType = mozilla::TimeDuration;
    236    static uint32_t convert(SourceType td) {
    237      return uint32_t(td.ToMicroseconds());
    238    }
    239  };
    240 
    241  // Record a metric in bytes. In the future these will be Glean Memory
    242  // Distribution metrics.
    243  struct MemoryDistribution {
    244    using SourceType = size_t;
    245    static uint32_t convert(SourceType sz) {
    246      return static_cast<uint32_t>(std::min(sz, size_t(UINT32_MAX)));
    247    }
    248  };
    249 
    250  // Record a metric for a quanity of items. This doesn't currently have a Glean
    251  // analogue and we avoid using MemoryDistribution directly to avoid confusion
    252  // about units.
    253  using QuantityDistribution = MemoryDistribution;
    254 
    255  // Record the distribution of boolean values. In the future this will be a
    256  // Glean Rate metric.
    257  struct Boolean {
    258    using SourceType = bool;
    259    static uint32_t convert(SourceType sample) {
    260      return static_cast<uint32_t>(sample);
    261    }
    262  };
    263 
    264  // Record the distribution of an enumeration value. This records integer
    265  // values so take care not to redefine the value of enum values. In the
    266  // future, these should become Glean Labeled Counter metrics.
    267  struct Enumeration {
    268    using SourceType = unsigned int;
    269    static uint32_t convert(SourceType sample) {
    270      MOZ_ASSERT(sample <= 100);
    271      return static_cast<uint32_t>(sample);
    272    }
    273  };
    274 
    275  // Record a percentage distribution in the range 0 to 100. This takes a double
    276  // and converts it to an integer. In the future, this will be a Glean Custom
    277  // Distribution unless they add a better match.
    278  struct Percentage {
    279    using SourceType = double;
    280    static uint32_t convert(SourceType sample) {
    281      MOZ_ASSERT(sample >= 0.0 && sample <= 100.0);
    282      return static_cast<uint32_t>(sample);
    283    }
    284  };
    285 
    286  // Record an unsigned integer.
    287  struct Integer {
    288    using SourceType = uint32_t;
    289    static uint32_t convert(SourceType sample) { return sample; }
    290  };
    291 
    292  inline void addTelemetry(JSMetric id, uint32_t sample);
    293 
    294 #define DECLARE_METRIC_HELPER(NAME, TY)                \
    295  void NAME(TY::SourceType sample) {                   \
    296    addTelemetry(JSMetric::NAME, TY::convert(sample)); \
    297  }
    298  FOR_EACH_JS_METRIC(DECLARE_METRIC_HELPER)
    299 #undef DECLARE_METRIC_HELPER
    300 };
    301 
    302 }  // namespace js
    303 
    304 struct JSRuntime {
    305 private:
    306  friend class js::Activation;
    307  friend class js::ActivationIterator;
    308  friend class js::jit::JitActivation;
    309  friend class js::jit::CompileRuntime;
    310 
    311  /* Space for interpreter frames. */
    312  js::MainThreadData<js::InterpreterStack> interpreterStack_;
    313 
    314 #ifdef ENABLE_PORTABLE_BASELINE_INTERP
    315  /* Space for portable baseline interpreter frames. */
    316  js::MainThreadData<js::PortableBaselineStack> portableBaselineStack_;
    317 #endif
    318 
    319 public:
    320  js::InterpreterStack& interpreterStack() { return interpreterStack_.ref(); }
    321 #ifdef ENABLE_PORTABLE_BASELINE_INTERP
    322  js::PortableBaselineStack& portableBaselineStack() {
    323    return portableBaselineStack_.ref();
    324  }
    325 #endif
    326 
    327  /*
    328   * If non-null, another runtime guaranteed to outlive this one and whose
    329   * permanent data may be used by this one where possible.
    330   */
    331  JSRuntime* const parentRuntime;
    332 
    333  bool isMainRuntime() const { return !parentRuntime; }
    334 
    335 #ifdef DEBUG
    336  /* The number of child runtimes that have this runtime as their parent. */
    337  mozilla::Atomic<size_t> childRuntimeCount;
    338 
    339  class AutoUpdateChildRuntimeCount {
    340    JSRuntime* parent_;
    341 
    342   public:
    343    explicit AutoUpdateChildRuntimeCount(JSRuntime* parent) : parent_(parent) {
    344      if (parent_) {
    345        parent_->childRuntimeCount++;
    346      }
    347    }
    348 
    349    ~AutoUpdateChildRuntimeCount() {
    350      if (parent_) {
    351        parent_->childRuntimeCount--;
    352      }
    353    }
    354  };
    355 
    356  AutoUpdateChildRuntimeCount updateChildRuntimeCount;
    357 #endif
    358 
    359 private:
    360 #ifdef DEBUG
    361  js::WriteOnceData<bool> initialized_;
    362 #endif
    363 
    364  // The JSContext* for the runtime's main thread. Immutable after this is set
    365  // in JSRuntime::init.
    366  JSContext* mainContext_;
    367 
    368 public:
    369  JSContext* mainContextFromAnyThread() const { return mainContext_; }
    370  const void* addressOfMainContext() { return &mainContext_; }
    371  js::Fprinter parserWatcherFile;
    372 
    373  inline JSContext* mainContextFromOwnThread();
    374 
    375  js::Metrics metrics() { return js::Metrics(this); }
    376 
    377  /*
    378   * The start of the range stored in the profiler sample buffer, as measured
    379   * after the most recent sample.
    380   * All JitcodeGlobalTable entries referenced from a given sample are
    381   * assigned the buffer position of the START of the sample. The buffer
    382   * entries that reference the JitcodeGlobalTable entries will only ever be
    383   * read from the buffer while the entire sample is still inside the buffer;
    384   * if some buffer entries at the start of the sample have left the buffer,
    385   * the entire sample will be considered inaccessible.
    386   * This means that, once profilerSampleBufferRangeStart_ advances beyond
    387   * the sample position that's stored on a JitcodeGlobalTable entry, the
    388   * buffer entries that reference this JitcodeGlobalTable entry will be
    389   * considered inaccessible, and those JitcodeGlobalTable entry can be
    390   * disposed of.
    391   */
    392  mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire>
    393      profilerSampleBufferRangeStart_;
    394 
    395  mozilla::Maybe<uint64_t> profilerSampleBufferRangeStart() {
    396    if (beingDestroyed_ || !geckoProfiler().enabled()) {
    397      return mozilla::Nothing();
    398    }
    399    uint64_t rangeStart = profilerSampleBufferRangeStart_;
    400    return mozilla::Some(rangeStart);
    401  }
    402  void setProfilerSampleBufferRangeStart(uint64_t rangeStart) {
    403    profilerSampleBufferRangeStart_ = rangeStart;
    404  }
    405 
    406  /* Call this to accumulate telemetry data. May be called from any thread; the
    407   * embedder is responsible for locking. */
    408  JSAccumulateTelemetryDataCallback telemetryCallback;
    409 
    410  /* Call this to accumulate use counter data. */
    411  js::MainThreadData<JSSetUseCounterCallback> useCounterCallback;
    412 
    413 public:
    414  // Accumulates data for Firefox telemetry.
    415  void addTelemetry(JSMetric id, uint32_t sample);
    416 
    417  void setTelemetryCallback(JSRuntime* rt,
    418                            JSAccumulateTelemetryDataCallback callback);
    419 
    420  // Sets the use counter for a specific feature, measuring the presence or
    421  // absence of usage of a feature on a specific web page and document which
    422  // the passed JSObject belongs to.
    423  void setUseCounter(JSObject* obj, JSUseCounter counter);
    424 
    425  void setUseCounterCallback(JSRuntime* rt, JSSetUseCounterCallback callback);
    426 
    427 public:
    428  js::UnprotectedData<js::OffThreadPromiseRuntimeState> offThreadPromiseState;
    429  js::UnprotectedData<JS::ConsumeStreamCallback> consumeStreamCallback;
    430  js::UnprotectedData<JS::ReportStreamErrorCallback> reportStreamErrorCallback;
    431 
    432  bool getHostDefinedData(JSContext* cx,
    433                          JS::MutableHandle<JSObject*> data) const;
    434 
    435  bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job,
    436                         js::HandleObject promise,
    437                         js::HandleObject hostDefinedData);
    438  void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
    439  void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
    440 
    441  /* Had an out-of-memory error which did not populate an exception. */
    442  mozilla::Atomic<bool, mozilla::SequentiallyConsistent> hadOutOfMemory;
    443 
    444  /*
    445   * Allow relazifying functions in compartments that are active. This is
    446   * only used by the relazifyFunctions() testing function.
    447   */
    448  js::MainThreadData<bool> allowRelazificationForTesting;
    449 
    450  /* Zone destroy callback. */
    451  js::MainThreadData<JSDestroyZoneCallback> destroyZoneCallback;
    452 
    453  /* Compartment destroy callback. */
    454  js::MainThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
    455 
    456  /* Compartment memory reporting callback. */
    457  js::MainThreadData<JSSizeOfIncludingThisCompartmentCallback>
    458      sizeOfIncludingThisCompartmentCallback;
    459 
    460  /* DOM event dispatch callback for testing. */
    461  js::MainThreadData<JS::DispatchDOMEventCallback> dispatchDOMEventCallback;
    462 
    463  /* Callback for creating ubi::Nodes representing DOM node objects. Set by
    464   * JS::ubi::SetConstructUbiNodeForDOMObjectCallback. Refer to
    465   * js/public/UbiNode.h.
    466   */
    467  void (*constructUbiNodeForDOMObjectCallback)(void*, JSObject*) = nullptr;
    468 
    469  /* Realm destroy callback. */
    470  js::MainThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
    471 
    472  /* Call this to get the name of a realm. */
    473  js::MainThreadData<JS::RealmNameCallback> realmNameCallback;
    474 
    475  js::MainThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
    476 
    477  js::MainThreadData<const JSSecurityCallbacks*> securityCallbacks;
    478  js::MainThreadData<const js::DOMCallbacks*> DOMcallbacks;
    479  js::MainThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
    480  js::MainThreadData<JSReadPrincipalsOp> readPrincipals;
    481 
    482  js::MainThreadData<JS::EnsureCanAddPrivateElementOp> canAddPrivateElement;
    483 
    484  /* Optional warning reporter. */
    485  js::MainThreadData<JS::WarningReporter> warningReporter;
    486 
    487  // Lazy self-hosted functions use a shared SelfHostedLazyScript instance
    488  // instead instead of a BaseScript. This contains the minimal pointers to
    489  // trampolines for the scripts to support direct jitCodeRaw calls.
    490  js::UnprotectedData<js::SelfHostedLazyScript> selfHostedLazyScript;
    491 
    492 private:
    493  // The self-hosted JS code is compiled as a Stencil which is then attached to
    494  // the Runtime. This is used to instantiate functions into realms on demand.
    495  js::WriteOnceData<js::frontend::CompilationInput*> selfHostStencilInput_;
    496  js::WriteOnceData<js::frontend::CompilationStencil*> selfHostStencil_;
    497 
    498 public:
    499  // The self-hosted stencil is immutable once attached to the runtime, so
    500  // worker runtimes directly use the stencil on the parent runtime.
    501  js::frontend::CompilationInput& selfHostStencilInput() {
    502    MOZ_ASSERT(hasSelfHostStencil());
    503    return *selfHostStencilInput_.ref();
    504  }
    505  js::frontend::CompilationStencil& selfHostStencil() {
    506    MOZ_ASSERT(hasSelfHostStencil());
    507    return *selfHostStencil_.ref();
    508  }
    509  bool hasSelfHostStencil() const { return bool(selfHostStencil_.ref()); }
    510 
    511  // A mapping from the name of self-hosted function to a ScriptIndex range of
    512  // the function and inner-functions within the self-hosted stencil.
    513  js::MainThreadData<
    514      JS::GCHashMap<js::PreBarriered<JSAtom*>, js::frontend::ScriptIndexRange,
    515                    js::DefaultHasher<JSAtom*>, js::SystemAllocPolicy>>
    516      selfHostScriptMap;
    517 
    518  struct JitCacheKey {
    519    JitCacheKey(JSAtom* name, bool isDebuggee)
    520        : name(name), isDebuggee(isDebuggee) {}
    521 
    522    js::PreBarriered<JSAtom*> name;
    523    bool isDebuggee;
    524 
    525    void trace(JSTracer* trc) {
    526      TraceNullableEdge(trc, &name, "JitCacheKey::name");
    527    }
    528  };
    529 
    530  struct JitCacheKeyHasher : public js::DefaultHasher<JitCacheKey> {
    531    using PreBarrieredAtomHasher = DefaultHasher<js::PreBarriered<JSAtom*>>;
    532 
    533    static js::HashNumber hash(const Lookup& key) {
    534      return mozilla::HashGeneric(key.name->hash(), key.isDebuggee);
    535    }
    536 
    537    static bool match(const JitCacheKey& key, const Lookup& lookup) {
    538      return PreBarrieredAtomHasher::match(key.name, lookup.name) &&
    539             key.isDebuggee == lookup.isDebuggee;
    540    }
    541  };
    542 
    543  // A cache for a self-hosted function's JitCode (managed through a
    544  // BaselineScript) keyed by script name and debuggee status.
    545  js::MainThreadData<js::GCHashMap<JitCacheKey, js::jit::BaselineScript*,
    546                                   JitCacheKeyHasher, js::SystemAllocPolicy>>
    547      selfHostJitCache;
    548 
    549  void clearSelfHostedJitCache();
    550 
    551 private:
    552  /* Gecko profiling metadata */
    553  js::UnprotectedData<js::GeckoProfilerRuntime> geckoProfiler_;
    554 
    555 public:
    556  js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
    557 
    558  // Heap GC roots for PersistentRooted pointers.
    559  js::MainThreadData<mozilla::EnumeratedArray<
    560      JS::RootKind, mozilla::LinkedList<js::PersistentRootedBase>,
    561      size_t(JS::RootKind::Limit)>>
    562      heapRoots;
    563 
    564  void tracePersistentRoots(JSTracer* trc);
    565  void finishPersistentRoots();
    566 
    567  void finishRoots();
    568 
    569 private:
    570  js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
    571 
    572 public:
    573  void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
    574  const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
    575 
    576  void commitPendingWrapperPreservations();
    577  void commitPendingWrapperPreservations(JS::Zone* zone);
    578 
    579  js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
    580  js::MainThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
    581  js::MainThreadData<js::HasReleasedWrapperCallback> hasReleasedWrapperCallback;
    582 
    583  js::MainThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
    584 
    585  js::MainThreadData<JS::CTypesActivityCallback> ctypesActivityCallback;
    586 
    587 private:
    588  // Script sources to compress off-thread. Only accessed by the main thread or
    589  // off-thread GC sweeping (GCRuntime::sweepCompressionTasks).
    590  using PendingCompressions =
    591      js::Vector<js::PendingSourceCompressionEntry, 4, js::SystemAllocPolicy>;
    592  js::MainThreadOrGCTaskData<PendingCompressions> pendingCompressions_;
    593 
    594 public:
    595  [[nodiscard]] bool addPendingCompressionEntry(js::ScriptSource* source) {
    596    return pendingCompressions().emplaceBack(this, source);
    597  }
    598  PendingCompressions& pendingCompressions() {
    599    return pendingCompressions_.ref();
    600  }
    601 
    602 private:
    603  js::WriteOnceData<const JSClass*> windowProxyClass_;
    604 
    605 public:
    606  const JSClass* maybeWindowProxyClass() const { return windowProxyClass_; }
    607  void setWindowProxyClass(const JSClass* clasp) { windowProxyClass_ = clasp; }
    608 
    609 private:
    610  // List of non-ephemeron weak containers to sweep during
    611  // beginSweepingSweepGroup.
    612  js::MainThreadData<mozilla::LinkedList<JS::detail::WeakCacheBase>>
    613      weakCaches_;
    614 
    615 public:
    616  mozilla::LinkedList<JS::detail::WeakCacheBase>& weakCaches() {
    617    return weakCaches_.ref();
    618  }
    619  void registerWeakCache(JS::detail::WeakCacheBase* cachep) {
    620    weakCaches().insertBack(cachep);
    621  }
    622 
    623  template <typename T>
    624  struct GlobalObjectWatchersLinkAccess {
    625    static const mozilla::DoublyLinkedListElement<T>& Get(const T* aThis) {
    626      return aThis->onNewGlobalObjectWatchersLink;
    627    }
    628    static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
    629      return aThis->onNewGlobalObjectWatchersLink;
    630    }
    631  };
    632 
    633  template <typename T>
    634  struct GarbageCollectionWatchersLinkAccess {
    635    static const mozilla::DoublyLinkedListElement<T>& Get(const T* aThis) {
    636      return aThis->onGarbageCollectionWatchersLink;
    637    }
    638    static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
    639      return aThis->onGarbageCollectionWatchersLink;
    640    }
    641  };
    642 
    643  using OnNewGlobalWatchersList =
    644      mozilla::DoublyLinkedList<js::Debugger,
    645                                GlobalObjectWatchersLinkAccess<js::Debugger>>;
    646  using OnGarbageCollectionWatchersList = mozilla::DoublyLinkedList<
    647      js::Debugger, GarbageCollectionWatchersLinkAccess<js::Debugger>>;
    648 
    649 private:
    650  /*
    651   * List of all enabled Debuggers that have onNewGlobalObject handler
    652   * methods established.
    653   */
    654  js::MainThreadData<OnNewGlobalWatchersList> onNewGlobalObjectWatchers_;
    655 
    656  /*
    657   * List of all enabled Debuggers that have onGarbageCollection handler
    658   * methods established.
    659   */
    660  js::MainThreadData<OnGarbageCollectionWatchersList>
    661      onGarbageCollectionWatchers_;
    662 
    663 public:
    664  OnNewGlobalWatchersList& onNewGlobalObjectWatchers() {
    665    return onNewGlobalObjectWatchers_.ref();
    666  }
    667 
    668  OnGarbageCollectionWatchersList& onGarbageCollectionWatchers() {
    669    return onGarbageCollectionWatchers_.ref();
    670  }
    671 
    672 private:
    673  /* Linked list of all Debugger objects in the runtime. */
    674  js::MainThreadData<mozilla::LinkedList<js::Debugger>> debuggerList_;
    675 
    676 public:
    677  mozilla::LinkedList<js::Debugger>& debuggerList() {
    678    return debuggerList_.ref();
    679  }
    680 
    681 public:
    682  JS::HeapState heapState() const { return gc.heapState(); }
    683 
    684  // How many realms there are across all zones. This number includes
    685  // off-thread context realms, so it isn't necessarily equal to the
    686  // number of realms visited by RealmsIter.
    687  js::MainThreadData<size_t> numRealms;
    688 
    689  // The Gecko Profiler may want to sample the allocations happening across the
    690  // browser. This callback can be registered to record the allocation.
    691  js::MainThreadData<JS::RecordAllocationsCallback> recordAllocationCallback;
    692  js::MainThreadData<double> allocationSamplingProbability;
    693 
    694 private:
    695  // Number of debuggee realms in the runtime.
    696  js::MainThreadData<size_t> numDebuggeeRealms_;
    697 
    698  // Number of debuggee realms in the runtime observing code coverage.
    699  js::MainThreadData<size_t> numDebuggeeRealmsObservingCoverage_;
    700 
    701 public:
    702  void incrementNumDebuggeeRealms();
    703  void decrementNumDebuggeeRealms();
    704 
    705  size_t numDebuggeeRealms() const { return numDebuggeeRealms_; }
    706 
    707  void incrementNumDebuggeeRealmsObservingCoverage();
    708  void decrementNumDebuggeeRealmsObservingCoverage();
    709 
    710  void startRecordingAllocations(double probability,
    711                                 JS::RecordAllocationsCallback callback);
    712  void stopRecordingAllocations();
    713  void ensureRealmIsRecordingAllocations(JS::Handle<js::GlobalObject*> global);
    714 
    715  /* Locale-specific callbacks for string conversion. */
    716  js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
    717 
    718  /* Default locale for Internationalization API */
    719  js::MainThreadData<js::UniqueChars> defaultLocale;
    720 
    721  /* If true, new scripts must be created with PC counter information. */
    722  js::MainThreadOrIonCompileData<bool> profilingScripts;
    723 
    724  /* Strong references on scripts held for PCCount profiling API. */
    725  js::MainThreadData<JS::PersistentRooted<js::ScriptAndCountsVector>*>
    726      scriptAndCountsVector;
    727 
    728  using RootedPlainObjVec = JS::PersistentRooted<
    729      JS::GCVector<js::PlainObject*, 0, js::SystemAllocPolicy>>;
    730  js::MainThreadData<js::UniquePtr<RootedPlainObjVec>> watchtowerTestingLog;
    731 
    732 private:
    733  /* Code coverage output. */
    734  js::UnprotectedData<js::coverage::LCovRuntime> lcovOutput_;
    735 
    736  /* Functions to call, together with data, when the runtime is being torn down.
    737   */
    738  js::MainThreadData<mozilla::Vector<std::pair<void (*)(void*), void*>, 4>>
    739      cleanupClosures;
    740 
    741 public:
    742  js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
    743 
    744  /* Register a cleanup function to be called during runtime shutdown. Do not
    745   * depend on the ordering of cleanup calls. */
    746  bool atExit(void (*function)(void*), void* data) {
    747    return cleanupClosures.ref().append(std::pair(function, data));
    748  }
    749 
    750 private:
    751  js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
    752 
    753 public:
    754  mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
    755      js::PropertyName* name);
    756 
    757  [[nodiscard]] bool createJitRuntime(JSContext* cx);
    758  js::jit::JitRuntime* jitRuntime() const { return jitRuntime_.ref(); }
    759  bool hasJitRuntime() const { return !!jitRuntime_; }
    760  static constexpr size_t offsetOfJitRuntime() {
    761    return offsetof(JSRuntime, jitRuntime_) +
    762           js::UnprotectedData<js::jit::JitRuntime*>::offsetOfValue();
    763  }
    764 
    765 private:
    766  // Used to generate random keys for hash tables.
    767  mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;
    768  mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator();
    769 
    770  // Used to generate random hash codes for symbols.
    771  mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG>
    772      randomHashCodeGenerator_;
    773 
    774 public:
    775  mozilla::HashCodeScrambler randomHashCodeScrambler();
    776  mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator();
    777 
    778  js::HashNumber randomHashCode();
    779 
    780  //-------------------------------------------------------------------------
    781  // Self-hosting support
    782  //-------------------------------------------------------------------------
    783 
    784  bool hasInitializedSelfHosting() const { return hasSelfHostStencil(); }
    785 
    786  bool initSelfHostingStencil(JSContext* cx, JS::SelfHostedCache xdrCache,
    787                              JS::SelfHostedWriter xdrWriter);
    788  bool initSelfHostingFromStencil(JSContext* cx);
    789  void finishSelfHosting();
    790  void traceSelfHostingStencil(JSTracer* trc);
    791  js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
    792  bool delazifySelfHostedFunction(JSContext* cx,
    793                                  js::Handle<js::PropertyName*> name,
    794                                  js::Handle<JSFunction*> targetFun);
    795  bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
    796                          js::MutableHandleValue vp);
    797  void assertSelfHostedFunctionHasCanonicalName(
    798      JS::Handle<js::PropertyName*> name);
    799 
    800 private:
    801  void setSelfHostingStencil(
    802      JS::MutableHandle<js::UniquePtr<js::frontend::CompilationInput>> input,
    803      RefPtr<js::frontend::CompilationStencil>&& stencil);
    804 
    805  //-------------------------------------------------------------------------
    806  // Locale information
    807  //-------------------------------------------------------------------------
    808 
    809 public:
    810  /*
    811   * Set the default locale for the ECMAScript Internationalization API
    812   * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
    813   * Note that the Internationalization API encourages clients to
    814   * specify their own locales.
    815   * The locale string remains owned by the caller.
    816   */
    817  bool setDefaultLocale(const char* locale);
    818 
    819  /* Reset the default locale to OS defaults. */
    820  void resetDefaultLocale();
    821 
    822  /* Gets current default locale. String remains owned by runtime. */
    823  const char* getDefaultLocale();
    824 
    825  /*
    826   * Gets current default locale or nullptr if not initialized.
    827   * String remains owned by runtime.
    828   */
    829  const char* getDefaultLocaleIfInitialized() const {
    830    return defaultLocale.ref().get();
    831  }
    832 
    833  /* Garbage collector state. */
    834  js::gc::GCRuntime gc;
    835 
    836  /* Garbage collector state has been successfully initialized. */
    837 
    838  bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
    839 
    840  void lockGC() { gc.lockGC(); }
    841 
    842  void unlockGC() { gc.unlockGC(); }
    843 
    844  js::WriteOnceData<js::PropertyName*> emptyString;
    845 
    846 public:
    847  JS::GCContext* gcContext() { return &gc.mainThreadContext.ref(); }
    848 
    849 #if !JS_HAS_INTL_API
    850  /* Number localization, used by jsnum.cpp. */
    851  js::WriteOnceData<const char*> thousandsSeparator;
    852  js::WriteOnceData<const char*> decimalSeparator;
    853  js::WriteOnceData<const char*> numGrouping;
    854 #endif
    855 
    856 private:
    857  js::WriteOnceData<bool> beingDestroyed_;
    858 
    859 public:
    860  bool isBeingDestroyed() const { return beingDestroyed_; }
    861 
    862 private:
    863  bool allowContentJS_;
    864 
    865 public:
    866  bool allowContentJS() const { return allowContentJS_; }
    867 
    868  friend class js::AutoAssertNoContentJS;
    869 
    870 private:
    871  // Table of all atoms other than those in permanentAtoms and staticStrings.
    872  js::WriteOnceData<js::AtomsTable*> atoms_;
    873 
    874  // Set of all live symbols produced by Symbol.for(). All such symbols are
    875  // allocated in the atoms zone. Reading or writing the symbol registry
    876  // can only be done from the main thread.
    877  js::MainThreadOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
    878 
    879  js::WriteOnceData<js::FrozenAtomSet*> permanentAtoms_;
    880 
    881 public:
    882  bool initializeAtoms(JSContext* cx);
    883  void finishAtoms();
    884  bool atomsAreFinished() const { return !atoms_; }
    885 
    886  js::AtomsTable* atomsForSweeping() {
    887    MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
    888    return atoms_;
    889  }
    890 
    891  js::AtomsTable& atoms() {
    892    MOZ_ASSERT(atoms_);
    893    return *atoms_;
    894  }
    895 
    896  JS::Zone* atomsZone() {
    897    MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this));
    898    return unsafeAtomsZone();
    899  }
    900  JS::Zone* unsafeAtomsZone() { return gc.atomsZone(); }
    901 
    902 #ifdef DEBUG
    903  bool isAtomsZone(const JS::Zone* zone) const {
    904    return JS::shadow::Zone::from(zone)->isAtomsZone();
    905  }
    906 #endif
    907 
    908  bool activeGCInAtomsZone();
    909 
    910  js::SymbolRegistry& symbolRegistry() { return symbolRegistry_.ref(); }
    911 
    912  // Permanent atoms are fixed during initialization of the runtime and are
    913  // not modified or collected until the runtime is destroyed. These may be
    914  // shared with another, longer living runtime through |parentRuntime| and
    915  // can be freely accessed with no locking necessary.
    916 
    917  // Permanent atoms pre-allocated for general use.
    918  js::WriteOnceData<js::StaticStrings*> staticStrings;
    919 
    920  // Cached pointers to various permanent property names.
    921  js::WriteOnceData<JSAtomState*> commonNames;
    922 
    923  // All permanent atoms in the runtime, other than those in staticStrings.
    924  // Access to this does not require a lock because it is frozen and thus
    925  // read-only.
    926  const js::FrozenAtomSet* permanentAtoms() const {
    927    MOZ_ASSERT(permanentAtomsPopulated());
    928    return permanentAtoms_.ref();
    929  }
    930 
    931  // The permanent atoms table is populated during initialization.
    932  bool permanentAtomsPopulated() const { return permanentAtoms_; }
    933 
    934  // Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
    935  // these are shared with the parentRuntime, if any.
    936  js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
    937 
    938 #ifdef JS_HAS_INTL_API
    939  /* Shared Intl data for this runtime. */
    940  js::MainThreadData<js::intl::SharedIntlData> sharedIntlData;
    941 
    942  void traceSharedIntlData(JSTracer* trc);
    943 #endif
    944 
    945 private:
    946  js::SharedScriptDataTableHolder scriptDataTableHolder_;
    947 
    948 public:
    949  // Returns the runtime's local script data table holder.
    950  js::SharedScriptDataTableHolder& scriptDataTableHolder();
    951 
    952 private:
    953  static mozilla::Atomic<size_t> liveRuntimesCount;
    954 
    955 public:
    956  static bool hasLiveRuntimes() { return liveRuntimesCount > 0; }
    957  static bool hasSingleLiveRuntime() { return liveRuntimesCount == 1; }
    958 
    959  explicit JSRuntime(JSRuntime* parentRuntime);
    960  ~JSRuntime();
    961 
    962  // destroyRuntime is used instead of a destructor, to ensure the downcast
    963  // to JSContext remains valid. The final GC triggered here depends on this.
    964  void destroyRuntime();
    965 
    966  bool init(JSContext* cx, uint32_t maxbytes);
    967 
    968  JSRuntime* thisFromCtor() { return this; }
    969 
    970 private:
    971  // Number of live SharedArrayBuffer objects, including those in Wasm shared
    972  // memories.  uint64_t to avoid any risk of overflow.
    973  js::MainThreadData<uint64_t> liveSABs;
    974 
    975 public:
    976  void incSABCount() {
    977    MOZ_RELEASE_ASSERT(liveSABs != UINT64_MAX);
    978    liveSABs++;
    979  }
    980 
    981  void decSABCount() {
    982    MOZ_RELEASE_ASSERT(liveSABs > 0);
    983    liveSABs--;
    984  }
    985 
    986  bool hasLiveSABs() const { return liveSABs > 0; }
    987 
    988 public:
    989  js::MainThreadData<JS::BeforeWaitCallback> beforeWaitCallback;
    990  js::MainThreadData<JS::AfterWaitCallback> afterWaitCallback;
    991 
    992 public:
    993  void reportAllocationOverflow() {
    994    js::ReportAllocationOverflow(static_cast<JSContext*>(nullptr));
    995  }
    996 
    997  /*
    998   * This should be called after system malloc/calloc/realloc returns nullptr
    999   * to try to recove some memory or to report an error.  For realloc, the
   1000   * original pointer must be passed as reallocPtr.
   1001   *
   1002   * The function must be called outside the GC lock.
   1003   */
   1004  JS_PUBLIC_API void* onOutOfMemory(js::AllocFunction allocator,
   1005                                    arena_id_t arena, size_t nbytes,
   1006                                    void* reallocPtr = nullptr,
   1007                                    JSContext* maybecx = nullptr);
   1008 
   1009  /*  onOutOfMemory but can call OnLargeAllocationFailure. */
   1010  JS_PUBLIC_API void* onOutOfMemoryCanGC(js::AllocFunction allocator,
   1011                                         arena_id_t arena, size_t nbytes,
   1012                                         void* reallocPtr = nullptr);
   1013 
   1014  static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
   1015 
   1016  void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
   1017                              JS::RuntimeSizes* rtSizes);
   1018 
   1019 private:
   1020  // Settings for how helper threads can be used.
   1021  mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
   1022      offthreadBaselineCompilationEnabled_;
   1023  mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
   1024      offthreadIonCompilationEnabled_;
   1025 
   1026  js::MainThreadData<bool> autoWritableJitCodeActive_;
   1027 
   1028 public:
   1029  // Note: these values may be toggled dynamically (in response to about:config
   1030  // prefs changing).
   1031  void setOffthreadBaselineCompilationEnabled(bool value) {
   1032    offthreadBaselineCompilationEnabled_ = value;
   1033  }
   1034  bool canUseOffthreadBaselineCompilation() const {
   1035    return offthreadBaselineCompilationEnabled_;
   1036  }
   1037  void setOffthreadIonCompilationEnabled(bool value) {
   1038    offthreadIonCompilationEnabled_ = value;
   1039  }
   1040  void setOffthreadCompilationEnabled(bool value) {
   1041    setOffthreadBaselineCompilationEnabled(value);
   1042    setOffthreadIonCompilationEnabled(value);
   1043  }
   1044  bool canUseOffthreadIonCompilation() const {
   1045    return offthreadIonCompilationEnabled_;
   1046  }
   1047  void toggleAutoWritableJitCodeActive(bool b) {
   1048    MOZ_ASSERT(autoWritableJitCodeActive_ != b,
   1049               "AutoWritableJitCode should not be nested.");
   1050    autoWritableJitCodeActive_ = b;
   1051  }
   1052 
   1053  /* See comment for JS::SetOutOfMemoryCallback in js/MemoryCallbacks.h. */
   1054  js::MainThreadData<JS::OutOfMemoryCallback> oomCallback;
   1055  js::MainThreadData<void*> oomCallbackData;
   1056 
   1057  /*
   1058   * Debugger.Memory functions like takeCensus use this embedding-provided
   1059   * function to assess the size of malloc'd blocks of memory.
   1060   */
   1061  js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
   1062 
   1063  /* Last time at which an animation was played for this runtime. */
   1064  js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
   1065 
   1066 private:
   1067  /* The stack format for the current runtime.  Only valid on non-child
   1068   * runtimes. */
   1069  mozilla::Atomic<js::StackFormat, mozilla::ReleaseAcquire> stackFormat_;
   1070 
   1071 public:
   1072  js::StackFormat stackFormat() const {
   1073    const JSRuntime* rt = this;
   1074    while (rt->parentRuntime) {
   1075      MOZ_ASSERT(rt->stackFormat_ == js::StackFormat::Default);
   1076      rt = rt->parentRuntime;
   1077    }
   1078    MOZ_ASSERT(rt->stackFormat_ != js::StackFormat::Default);
   1079    return rt->stackFormat_;
   1080  }
   1081  void setStackFormat(js::StackFormat format) {
   1082    MOZ_ASSERT(!parentRuntime);
   1083    MOZ_ASSERT(format != js::StackFormat::Default);
   1084    stackFormat_ = format;
   1085  }
   1086 
   1087 private:
   1088  // Warning: no data should be accessed in these caches from another thread,
   1089  // but Ion needs to be able to access addresses inside here, which should be
   1090  // safe, as the actual cache lookups will be performed on the main thread
   1091  // through jitted code.
   1092  js::MainThreadOrIonCompileData<js::RuntimeCaches> caches_;
   1093 
   1094 public:
   1095  js::RuntimeCaches& caches() { return caches_.ref(); }
   1096 
   1097  // List of all the live wasm::Instances in the runtime. Equal to the union
   1098  // of all instances registered in all JS::Realms. Accessed from watchdog
   1099  // threads for purposes of wasm::InterruptRunningCode().
   1100  js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
   1101 
   1102  // The [[ModuleAsyncEvaluationCount]] field of agent records
   1103  //
   1104  // See https://tc39.es/ecma262/#sec-agents.
   1105  js::MainThreadData<uint32_t> moduleAsyncEvaluatingPostOrder;
   1106 
   1107  // A counter used to detect when there are no pending async modules, so
   1108  // that we can reset [[ModuleAsyncEvaluationCount]] to 0.
   1109  //
   1110  // See the note in
   1111  // https://tc39.es/ecma262/#sec-IncrementModuleAsyncEvaluationCount for use.
   1112  js::MainThreadData<uint32_t> pendingAsyncModuleEvaluations;
   1113 
   1114  // The implementation-defined abstract operation HostLoadImportedModule.
   1115  js::MainThreadData<JS::ModuleLoadHook> moduleLoadHook;
   1116 
   1117  // A hook that implements the abstract operations
   1118  // HostGetImportMetaProperties and HostFinalizeImportMeta.
   1119  js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
   1120 
   1121  // Hooks called when script private references are created and destroyed.
   1122  js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateAddRefHook;
   1123  js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateReleaseHook;
   1124 
   1125  void addRefScriptPrivate(const JS::Value& value) {
   1126    if (!value.isUndefined() && scriptPrivateAddRefHook) {
   1127      scriptPrivateAddRefHook(value);
   1128    }
   1129  }
   1130 
   1131  void releaseScriptPrivate(const JS::Value& value) {
   1132    if (!value.isUndefined() && scriptPrivateReleaseHook) {
   1133      scriptPrivateReleaseHook(value);
   1134    }
   1135  }
   1136 
   1137 public:
   1138 #if defined(NIGHTLY_BUILD)
   1139  // Support for informing the embedding of any error thrown.
   1140  // This mechanism is designed to let the embedding
   1141  // log/report/fail in case certain errors are thrown
   1142  // (e.g. SyntaxError, ReferenceError or TypeError
   1143  // in critical code).
   1144  struct ErrorInterceptionSupport {
   1145    ErrorInterceptionSupport() : isExecuting(false), interceptor(nullptr) {}
   1146 
   1147    // true if the error interceptor is currently executing,
   1148    // false otherwise. Used to avoid infinite loops.
   1149    bool isExecuting;
   1150 
   1151    // if non-null, any call to `setPendingException`
   1152    // in this runtime will trigger the call to `interceptor`
   1153    JSErrorInterceptor* interceptor;
   1154  };
   1155  ErrorInterceptionSupport errorInterception;
   1156 #endif  // defined(NIGHTLY_BUILD)
   1157 
   1158 public:
   1159  JS::GlobalInitializeCallback getShadowRealmInitializeGlobalCallback() {
   1160    return shadowRealmInitializeGlobalCallback;
   1161  }
   1162 
   1163  JS::GlobalCreationCallback getShadowRealmGlobalCreationCallback() {
   1164    return shadowRealmGlobalCreationCallback;
   1165  }
   1166 
   1167  js::MainThreadData<JS::GlobalInitializeCallback>
   1168      shadowRealmInitializeGlobalCallback;
   1169 
   1170  js::MainThreadData<JS::GlobalCreationCallback>
   1171      shadowRealmGlobalCreationCallback;
   1172 
   1173  js::MainThreadData<js::RuntimeFuses> runtimeFuses;
   1174 };
   1175 
   1176 namespace js {
   1177 
   1178 void Metrics::addTelemetry(JSMetric id, uint32_t sample) {
   1179  rt_->addTelemetry(id, sample);
   1180 }
   1181 
   1182 extern const JSSecurityCallbacks NullSecurityCallbacks;
   1183 
   1184 // This callback is set by JS::SetProcessLargeAllocationFailureCallback
   1185 // and may be null. See comment in jsapi.h.
   1186 extern mozilla::Atomic<JS::LargeAllocationFailureCallback>
   1187    OnLargeAllocationFailure;
   1188 
   1189 // This callback is set by JS::SetBuildIdOp and may be null. See comment in
   1190 // jsapi.h.
   1191 extern mozilla::Atomic<JS::BuildIdOp> GetBuildId;
   1192 
   1193 extern JS::FilenameValidationCallback gFilenameValidationCallback;
   1194 
   1195 } /* namespace js */
   1196 
   1197 #endif /* vm_Runtime_h */