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/MaybeOneOf.h"
17 #include "mozilla/MemoryReporting.h"
18 #include "mozilla/ThreadLocal.h"
19 #include "mozilla/TimeStamp.h"
20 #include "mozilla/Vector.h"
21 #include "mozilla/XorShift128PlusRNG.h"
22 
23 #include <algorithm>
24 
25 #include "builtin/AtomicsObject.h"
26 #ifdef JS_HAS_INTL_API
27 #  include "builtin/intl/SharedIntlData.h"
28 #endif
29 #include "frontend/ScriptIndex.h"
30 #include "gc/GCRuntime.h"
31 #include "gc/Tracer.h"
32 #include "js/AllocationRecording.h"
33 #include "js/BuildId.h"  // JS::BuildIdOp
34 #include "js/CompilationAndEvaluation.h"
35 #include "js/Context.h"
36 #include "js/Debug.h"
37 #include "js/experimental/CTypes.h"      // JS::CTypesActivityCallback
38 #include "js/experimental/JSStencil.h"   // mozilla::RefPtrTraits<JS::Stencil>
39 #include "js/experimental/SourceHook.h"  // js::SourceHook
40 #include "js/friend/StackLimits.h"       // js::ReportOverRecursed
41 #include "js/friend/UsageStatistics.h"   // JSAccumulateTelemetryDataCallback
42 #include "js/GCVector.h"
43 #include "js/HashTable.h"
44 #include "js/Initialization.h"
45 #include "js/MemoryCallbacks.h"
46 #include "js/Modules.h"  // JS::Module{DynamicImport,Metadata,Resolve}Hook
47 #ifdef DEBUG
48 #  include "js/Proxy.h"  // For AutoEnterPolicy
49 #endif
50 #include "js/ScriptPrivate.h"
51 #include "js/Stack.h"
52 #include "js/Stream.h"  // JS::AbortSignalIsAborted
53 #include "js/StreamConsumer.h"
54 #include "js/Symbol.h"
55 #include "js/UniquePtr.h"
56 #include "js/Utility.h"
57 #include "js/Vector.h"
58 #include "js/WaitCallbacks.h"
59 #include "js/Warnings.h"  // JS::WarningReporter
60 #include "js/WrapperCallbacks.h"
61 #include "js/Zone.h"
62 #include "threading/Thread.h"
63 #include "vm/Caches.h"  // js::RuntimeCaches
64 #include "vm/CodeCoverage.h"
65 #include "vm/CommonPropertyNames.h"
66 #include "vm/GeckoProfiler.h"
67 #include "vm/JSAtom.h"
68 #include "vm/JSAtomState.h"
69 #include "vm/JSScript.h"
70 #include "vm/OffThreadPromiseRuntimeState.h"  // js::OffThreadPromiseRuntimeState
71 #include "vm/Scope.h"
72 #include "vm/SharedImmutableStringsCache.h"
73 #include "vm/SharedStencil.h"  // js::SharedImmutableScriptDataTable
74 #include "vm/Stack.h"
75 #include "vm/SymbolType.h"
76 #include "wasm/WasmTypeDecls.h"
77 
78 struct JSClass;
79 struct JSErrorInterceptor;
80 
81 namespace js {
82 
83 class AutoAssertNoContentJS;
84 class EnterDebuggeeNoExecute;
85 #ifdef JS_TRACE_LOGGING
86 class TraceLoggerThread;
87 #endif
88 
89 }  // namespace js
90 
91 struct DtoaState;
92 struct JSLocaleCallbacks;
93 
94 #ifdef JS_SIMULATOR_ARM64
95 namespace vixl {
96 class Simulator;
97 }
98 #endif
99 
100 namespace js {
101 
102 extern MOZ_COLD void ReportOutOfMemory(JSContext* cx);
103 extern MOZ_COLD void ReportAllocationOverflow(JSContext* maybecx);
104 extern MOZ_COLD void ReportOversizedAllocation(JSContext* cx,
105                                                const unsigned errorNumber);
106 
107 class Activation;
108 class ActivationIterator;
109 
110 namespace jit {
111 class JitRuntime;
112 class JitActivation;
113 struct PcScriptCache;
114 class CompileRuntime;
115 
116 #ifdef JS_SIMULATOR_ARM64
117 typedef vixl::Simulator Simulator;
118 #elif defined(JS_SIMULATOR)
119 class Simulator;
120 #endif
121 }  // namespace jit
122 
123 namespace frontend {
124 struct CompilationGCOutput;
125 struct CompilationInput;
126 struct CompilationStencil;
127 class WellKnownParserAtoms;
128 }  // namespace frontend
129 
130 // [SMDOC] JS Engine Threading
131 //
132 // Threads interacting with a runtime are divided into two categories:
133 //
134 // - The main thread is capable of running JS. There's at most one main thread
135 //   per runtime.
136 //
137 // - Helper threads do not run JS, and are controlled or triggered by activity
138 //   on the main thread (or main threads, since all runtimes in a process share
139 //   helper threads). Helper threads may have exclusive access to zones created
140 //   for them, for parsing and similar tasks, but their activities do not cause
141 //   observable changes in script behaviors. Activity on helper threads may be
142 //   referred to as happening 'off thread' or on a background thread in some
143 //   parts of the VM.
144 
145 } /* namespace js */
146 
147 namespace JS {
148 struct RuntimeSizes;
149 }  // namespace JS
150 
151 namespace js {
152 
153 /*
154  * Storage for well-known symbols. It's a separate struct from the Runtime so
155  * that it can be shared across multiple runtimes. As in JSAtomState, each
156  * field is a smart pointer that's immutable once initialized.
157  * `rt->wellKnownSymbols->iterator` is convertible to Handle<Symbol*>.
158  *
159  * Well-known symbols are never GC'd. The description() of each well-known
160  * symbol is a permanent atom.
161  */
162 struct WellKnownSymbols {
163 #define DECLARE_SYMBOL(name) js::ImmutableSymbolPtr name;
JS_FOR_EACH_WELL_KNOWN_SYMBOLWellKnownSymbols164   JS_FOR_EACH_WELL_KNOWN_SYMBOL(DECLARE_SYMBOL)
165 #undef DECLARE_SYMBOL
166 
167   const ImmutableSymbolPtr& get(size_t u) const {
168     MOZ_ASSERT(u < JS::WellKnownSymbolLimit);
169     const ImmutableSymbolPtr* symbols =
170         reinterpret_cast<const ImmutableSymbolPtr*>(this);
171     return symbols[u];
172   }
173 
getWellKnownSymbols174   const ImmutableSymbolPtr& get(JS::SymbolCode code) const {
175     return get(size_t(code));
176   }
177 
178   WellKnownSymbols() = default;
179   WellKnownSymbols(const WellKnownSymbols&) = delete;
180   WellKnownSymbols& operator=(const WellKnownSymbols&) = delete;
181 };
182 
183 // There are several coarse locks in the enum below. These may be either
184 // per-runtime or per-process. When acquiring more than one of these locks,
185 // the acquisition must be done in the order below to avoid deadlocks.
186 enum RuntimeLock { HelperThreadStateLock, GCLock };
187 
CanUseExtraThreads()188 inline bool CanUseExtraThreads() {
189   extern bool gCanUseExtraThreads;
190   return gCanUseExtraThreads;
191 }
192 
193 void DisableExtraThreads();
194 
195 using ScriptAndCountsVector = GCVector<ScriptAndCounts, 0, SystemAllocPolicy>;
196 
197 class AutoLockScriptData;
198 
199 // Self-hosted lazy functions do not maintain a BaseScript as we can clone from
200 // the copy in the self-hosting zone. To allow these functions to be called by
201 // the JITs, we need a minimal script object. There is one instance per runtime.
202 struct SelfHostedLazyScript {
203   SelfHostedLazyScript() = default;
204 
205   // Pointer to interpreter trampoline. This field is stored at same location as
206   // in BaseScript::jitCodeRaw_.
207   uint8_t* jitCodeRaw_ = nullptr;
208 
209   // Warm-up count of zero. This field is stored at the same offset as
210   // BaseScript::warmUpData_.
211   ScriptWarmUpData warmUpData_ = {};
212 
offsetOfJitCodeRawSelfHostedLazyScript213   static constexpr size_t offsetOfJitCodeRaw() {
214     return offsetof(SelfHostedLazyScript, jitCodeRaw_);
215   }
offsetOfWarmUpDataSelfHostedLazyScript216   static constexpr size_t offsetOfWarmUpData() {
217     return offsetof(SelfHostedLazyScript, warmUpData_);
218   }
219 };
220 
221 }  // namespace js
222 
223 struct JSTelemetrySender;
224 
225 struct JSRuntime {
226  private:
227   friend class js::Activation;
228   friend class js::ActivationIterator;
229   friend class js::jit::JitActivation;
230   friend class js::jit::CompileRuntime;
231 
232   /* Space for interpreter frames. */
233   js::MainThreadData<js::InterpreterStack> interpreterStack_;
234 
235  public:
interpreterStackJSRuntime236   js::InterpreterStack& interpreterStack() { return interpreterStack_.ref(); }
237 
238   /*
239    * If non-null, another runtime guaranteed to outlive this one and whose
240    * permanent data may be used by this one where possible.
241    */
242   JSRuntime* const parentRuntime;
243 
isMainRuntimeJSRuntime244   bool isMainRuntime() const { return !parentRuntime; }
245 
246 #ifdef DEBUG
247   /* The number of child runtimes that have this runtime as their parent. */
248   mozilla::Atomic<size_t> childRuntimeCount;
249 
250   class AutoUpdateChildRuntimeCount {
251     JSRuntime* parent_;
252 
253    public:
AutoUpdateChildRuntimeCountJSRuntime254     explicit AutoUpdateChildRuntimeCount(JSRuntime* parent) : parent_(parent) {
255       if (parent_) {
256         parent_->childRuntimeCount++;
257       }
258     }
259 
~AutoUpdateChildRuntimeCountJSRuntime260     ~AutoUpdateChildRuntimeCount() {
261       if (parent_) {
262         parent_->childRuntimeCount--;
263       }
264     }
265   };
266 
267   AutoUpdateChildRuntimeCount updateChildRuntimeCount;
268 #endif
269 
270  private:
271 #ifdef DEBUG
272   js::WriteOnceData<bool> initialized_;
273 #endif
274 
275   // The JSContext* for the runtime's main thread. Immutable after this is set
276   // in JSRuntime::init.
277   JSContext* mainContext_;
278 
279  public:
mainContextFromAnyThreadJSRuntime280   JSContext* mainContextFromAnyThread() const { return mainContext_; }
addressOfMainContextJSRuntime281   const void* addressOfMainContext() { return &mainContext_; }
282   js::Fprinter parserWatcherFile;
283 
284   inline JSContext* mainContextFromOwnThread();
285 
286   /*
287    * The start of the range stored in the profiler sample buffer, as measured
288    * after the most recent sample.
289    * All JitcodeGlobalTable entries referenced from a given sample are
290    * assigned the buffer position of the START of the sample. The buffer
291    * entries that reference the JitcodeGlobalTable entries will only ever be
292    * read from the buffer while the entire sample is still inside the buffer;
293    * if some buffer entries at the start of the sample have left the buffer,
294    * the entire sample will be considered inaccessible.
295    * This means that, once profilerSampleBufferRangeStart_ advances beyond
296    * the sample position that's stored on a JitcodeGlobalTable entry, the
297    * buffer entries that reference this JitcodeGlobalTable entry will be
298    * considered inaccessible, and those JitcodeGlobalTable entry can be
299    * disposed of.
300    */
301   mozilla::Atomic<uint64_t, mozilla::ReleaseAcquire>
302       profilerSampleBufferRangeStart_;
303 
profilerSampleBufferRangeStartJSRuntime304   mozilla::Maybe<uint64_t> profilerSampleBufferRangeStart() {
305     if (beingDestroyed_ || !geckoProfiler().enabled()) {
306       return mozilla::Nothing();
307     }
308     uint64_t rangeStart = profilerSampleBufferRangeStart_;
309     return mozilla::Some(rangeStart);
310   }
setProfilerSampleBufferRangeStartJSRuntime311   void setProfilerSampleBufferRangeStart(uint64_t rangeStart) {
312     profilerSampleBufferRangeStart_ = rangeStart;
313   }
314 
315   /* Call this to accumulate telemetry data. May be called from any thread; the
316    * embedder is responsible for locking. */
317   JSAccumulateTelemetryDataCallback telemetryCallback;
318 
319   /* Call this to accumulate use counter data. */
320   js::MainThreadData<JSSetUseCounterCallback> useCounterCallback;
321 
322   js::MainThreadData<JSSourceElementCallback> sourceElementCallback;
323 
324  public:
325   // Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
326   // histogram. |key| provides an additional key to identify the histogram.
327   // |sample| is the data to add to the histogram.
328   void addTelemetry(int id, uint32_t sample, const char* key = nullptr);
329 
330   JSTelemetrySender getTelemetrySender() const;
331 
332   void setTelemetryCallback(JSRuntime* rt,
333                             JSAccumulateTelemetryDataCallback callback);
334 
335   void setSourceElementCallback(JSRuntime* rt,
336                                 JSSourceElementCallback callback);
337 
338   // Sets the use counter for a specific feature, measuring the presence or
339   // absence of usage of a feature on a specific web page and document which
340   // the passed JSObject belongs to.
341   void setUseCounter(JSObject* obj, JSUseCounter counter);
342 
343   void setUseCounterCallback(JSRuntime* rt, JSSetUseCounterCallback callback);
344 
345  public:
346   js::UnprotectedData<js::OffThreadPromiseRuntimeState> offThreadPromiseState;
347   js::UnprotectedData<JS::ConsumeStreamCallback> consumeStreamCallback;
348   js::UnprotectedData<JS::ReportStreamErrorCallback> reportStreamErrorCallback;
349 
350   js::GlobalObject* getIncumbentGlobal(JSContext* cx);
351   bool enqueuePromiseJob(JSContext* cx, js::HandleFunction job,
352                          js::HandleObject promise,
353                          js::Handle<js::GlobalObject*> incumbentGlobal);
354   void addUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
355   void removeUnhandledRejectedPromise(JSContext* cx, js::HandleObject promise);
356 
357   /* Had an out-of-memory error which did not populate an exception. */
358   mozilla::Atomic<bool, mozilla::SequentiallyConsistent> hadOutOfMemory;
359 
360   /*
361    * Allow relazifying functions in compartments that are active. This is
362    * only used by the relazifyFunctions() testing function.
363    */
364   js::MainThreadData<bool> allowRelazificationForTesting;
365 
366   /* Zone destroy callback. */
367   js::MainThreadData<JSDestroyZoneCallback> destroyZoneCallback;
368 
369   /* Compartment destroy callback. */
370   js::MainThreadData<JSDestroyCompartmentCallback> destroyCompartmentCallback;
371 
372   /* Compartment memory reporting callback. */
373   js::MainThreadData<JSSizeOfIncludingThisCompartmentCallback>
374       sizeOfIncludingThisCompartmentCallback;
375 
376   /* Callback for creating ubi::Nodes representing DOM node objects. Set by
377    * JS::ubi::SetConstructUbiNodeForDOMObjectCallback. Refer to
378    * js/public/UbiNode.h.
379    */
380   void (*constructUbiNodeForDOMObjectCallback)(void*, JSObject*) = nullptr;
381 
382   /* Realm destroy callback. */
383   js::MainThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
384 
385   /* Call this to get the name of a realm. */
386   js::MainThreadData<JS::RealmNameCallback> realmNameCallback;
387 
388   js::MainThreadData<mozilla::UniquePtr<js::SourceHook>> sourceHook;
389 
390   js::MainThreadData<const JSSecurityCallbacks*> securityCallbacks;
391   js::MainThreadData<const js::DOMCallbacks*> DOMcallbacks;
392   js::MainThreadData<JSDestroyPrincipalsOp> destroyPrincipals;
393   js::MainThreadData<JSReadPrincipalsOp> readPrincipals;
394 
395   /* Optional warning reporter. */
396   js::MainThreadData<JS::WarningReporter> warningReporter;
397 
398   // Lazy self-hosted functions use a shared SelfHostedLazyScript instance
399   // instead instead of a BaseScript. This contains the minimal pointers to
400   // trampolines for the scripts to support direct jitCodeRaw calls.
401   js::UnprotectedData<js::SelfHostedLazyScript> selfHostedLazyScript;
402 
403  private:
404   // The self-hosted JS code is compiled as a Stencil which is then attached to
405   // the Runtime. This is used to instantiate functions into realms on demand.
406   js::WriteOnceData<js::frontend::CompilationInput*> selfHostStencilInput_;
407   js::WriteOnceData<js::frontend::CompilationStencil*> selfHostStencil_;
408 
409  public:
410   // The self-hosted stencil is immutable once attached to the runtime, so
411   // worker runtimes directly use the stencil on the parent runtime.
selfHostStencilInputJSRuntime412   js::frontend::CompilationInput& selfHostStencilInput() {
413     MOZ_ASSERT(hasSelfHostStencil());
414     return *selfHostStencilInput_.ref();
415   }
selfHostStencilJSRuntime416   js::frontend::CompilationStencil& selfHostStencil() {
417     MOZ_ASSERT(hasSelfHostStencil());
418     return *selfHostStencil_.ref();
419   }
hasSelfHostStencilJSRuntime420   bool hasSelfHostStencil() const { return bool(selfHostStencil_.ref()); }
421 
422   // A mapping from the name of self-hosted function to a ScriptIndex range of
423   // the function and inner-functions within the self-hosted stencil.
424   js::MainThreadData<
425       JS::GCHashMap<js::PreBarriered<JSAtom*>, js::frontend::ScriptIndexRange,
426                     js::DefaultHasher<JSAtom*>, js::SystemAllocPolicy>>
427       selfHostScriptMap;
428 
429  private:
430   /* Gecko profiling metadata */
431   js::UnprotectedData<js::GeckoProfilerRuntime> geckoProfiler_;
432 
433  public:
geckoProfilerJSRuntime434   js::GeckoProfilerRuntime& geckoProfiler() { return geckoProfiler_.ref(); }
435 
436   // Heap GC roots for PersistentRooted pointers.
437   js::MainThreadData<
438       mozilla::EnumeratedArray<JS::RootKind, JS::RootKind::Limit,
439                                mozilla::LinkedList<js::PersistentRootedBase>>>
440       heapRoots;
441 
442   void tracePersistentRoots(JSTracer* trc);
443   void finishPersistentRoots();
444 
445   void finishRoots();
446 
447  private:
448   js::UnprotectedData<const JSPrincipals*> trustedPrincipals_;
449 
450  public:
setTrustedPrincipalsJSRuntime451   void setTrustedPrincipals(const JSPrincipals* p) { trustedPrincipals_ = p; }
trustedPrincipalsJSRuntime452   const JSPrincipals* trustedPrincipals() const { return trustedPrincipals_; }
453 
454   js::MainThreadData<const JSWrapObjectCallbacks*> wrapObjectCallbacks;
455   js::MainThreadData<js::PreserveWrapperCallback> preserveWrapperCallback;
456   js::MainThreadData<js::HasReleasedWrapperCallback> hasReleasedWrapperCallback;
457 
458   js::MainThreadData<js::ScriptEnvironmentPreparer*> scriptEnvironmentPreparer;
459 
460   js::MainThreadData<JS::CTypesActivityCallback> ctypesActivityCallback;
461 
462  private:
463   js::WriteOnceData<const JSClass*> windowProxyClass_;
464 
465  public:
maybeWindowProxyClassJSRuntime466   const JSClass* maybeWindowProxyClass() const { return windowProxyClass_; }
setWindowProxyClassJSRuntime467   void setWindowProxyClass(const JSClass* clasp) { windowProxyClass_ = clasp; }
468 
469  private:
470   js::WriteOnceData<const JSClass*> abortSignalClass_;
471   js::WriteOnceData<JS::AbortSignalIsAborted> abortSignalIsAborted_;
472 
473  public:
initPipeToHandlingJSRuntime474   void initPipeToHandling(const JSClass* abortSignalClass,
475                           JS::AbortSignalIsAborted isAborted) {
476     MOZ_ASSERT(abortSignalClass != nullptr,
477                "doesn't make sense for an embedder to provide a null class "
478                "when specifying pipeTo handling");
479     MOZ_ASSERT(isAborted != nullptr, "must pass a valid function pointer");
480 
481     abortSignalClass_ = abortSignalClass;
482     abortSignalIsAborted_ = isAborted;
483   }
484 
maybeAbortSignalClassJSRuntime485   const JSClass* maybeAbortSignalClass() const { return abortSignalClass_; }
486 
abortSignalIsAbortedJSRuntime487   bool abortSignalIsAborted(JSObject* obj) {
488     MOZ_ASSERT(abortSignalIsAborted_ != nullptr,
489                "must call initPipeToHandling first");
490     return abortSignalIsAborted_(obj);
491   }
492 
493  private:
494   // List of non-ephemeron weak containers to sweep during
495   // beginSweepingSweepGroup.
496   js::MainThreadData<mozilla::LinkedList<JS::detail::WeakCacheBase>>
497       weakCaches_;
498 
499  public:
weakCachesJSRuntime500   mozilla::LinkedList<JS::detail::WeakCacheBase>& weakCaches() {
501     return weakCaches_.ref();
502   }
registerWeakCacheJSRuntime503   void registerWeakCache(JS::detail::WeakCacheBase* cachep) {
504     weakCaches().insertBack(cachep);
505   }
506 
507   template <typename T>
508   struct GlobalObjectWatchersLinkAccess {
GetJSRuntime::GlobalObjectWatchersLinkAccess509     static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
510       return aThis->onNewGlobalObjectWatchersLink;
511     }
512   };
513 
514   template <typename T>
515   struct GarbageCollectionWatchersLinkAccess {
GetJSRuntime::GarbageCollectionWatchersLinkAccess516     static mozilla::DoublyLinkedListElement<T>& Get(T* aThis) {
517       return aThis->onGarbageCollectionWatchersLink;
518     }
519   };
520 
521   using OnNewGlobalWatchersList =
522       mozilla::DoublyLinkedList<js::Debugger,
523                                 GlobalObjectWatchersLinkAccess<js::Debugger>>;
524   using OnGarbageCollectionWatchersList = mozilla::DoublyLinkedList<
525       js::Debugger, GarbageCollectionWatchersLinkAccess<js::Debugger>>;
526 
527  private:
528   /*
529    * List of all enabled Debuggers that have onNewGlobalObject handler
530    * methods established.
531    */
532   js::MainThreadData<OnNewGlobalWatchersList> onNewGlobalObjectWatchers_;
533 
534   /*
535    * List of all enabled Debuggers that have onGarbageCollection handler
536    * methods established.
537    */
538   js::MainThreadData<OnGarbageCollectionWatchersList>
539       onGarbageCollectionWatchers_;
540 
541  public:
onNewGlobalObjectWatchersJSRuntime542   OnNewGlobalWatchersList& onNewGlobalObjectWatchers() {
543     return onNewGlobalObjectWatchers_.ref();
544   }
545 
onGarbageCollectionWatchersJSRuntime546   OnGarbageCollectionWatchersList& onGarbageCollectionWatchers() {
547     return onGarbageCollectionWatchers_.ref();
548   }
549 
550  private:
551   /* Linked list of all Debugger objects in the runtime. */
552   js::MainThreadData<mozilla::LinkedList<js::Debugger>> debuggerList_;
553 
554  public:
debuggerListJSRuntime555   mozilla::LinkedList<js::Debugger>& debuggerList() {
556     return debuggerList_.ref();
557   }
558 
559  private:
560   /*
561    * Lock used to protect the script data table, which can be used by
562    * off-thread parsing.
563    *
564    * Locking this only occurs if there is actually a thread other than the
565    * main thread which could access this.
566    */
567   js::Mutex scriptDataLock;
568 #ifdef DEBUG
569   bool activeThreadHasScriptDataAccess;
570 #endif
571 
572   // Number of off-thread ParseTasks that are using this runtime. This is only
573   // updated on main-thread. If this is non-zero we must use `scriptDataLock` to
574   // protect access to the bytecode table;
575   mozilla::Atomic<size_t, mozilla::SequentiallyConsistent> numParseTasks;
576 
577   friend class js::AutoLockScriptData;
578 
579  public:
hasParseTasksJSRuntime580   bool hasParseTasks() const { return numParseTasks > 0; }
581 
addParseTaskRefJSRuntime582   void addParseTaskRef() { numParseTasks++; }
decParseTaskRefJSRuntime583   void decParseTaskRef() { numParseTasks--; }
584 
585 #ifdef DEBUG
assertCurrentThreadHasScriptDataAccessJSRuntime586   void assertCurrentThreadHasScriptDataAccess() const {
587     if (!hasParseTasks()) {
588       MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this) &&
589                  activeThreadHasScriptDataAccess);
590       return;
591     }
592 
593     scriptDataLock.assertOwnedByCurrentThread();
594   }
595 #endif
596 
heapStateJSRuntime597   JS::HeapState heapState() const { return gc.heapState(); }
598 
599   // How many realms there are across all zones. This number includes
600   // off-thread context realms, so it isn't necessarily equal to the
601   // number of realms visited by RealmsIter.
602   js::MainThreadData<size_t> numRealms;
603 
604   // The Gecko Profiler may want to sample the allocations happening across the
605   // browser. This callback can be registered to record the allocation.
606   js::MainThreadData<JS::RecordAllocationsCallback> recordAllocationCallback;
607   js::MainThreadData<double> allocationSamplingProbability;
608 
609  private:
610   // Number of debuggee realms in the runtime.
611   js::MainThreadData<size_t> numDebuggeeRealms_;
612 
613   // Number of debuggee realms in the runtime observing code coverage.
614   js::MainThreadData<size_t> numDebuggeeRealmsObservingCoverage_;
615 
616  public:
617   void incrementNumDebuggeeRealms();
618   void decrementNumDebuggeeRealms();
619 
numDebuggeeRealmsJSRuntime620   size_t numDebuggeeRealms() const { return numDebuggeeRealms_; }
621 
622   void incrementNumDebuggeeRealmsObservingCoverage();
623   void decrementNumDebuggeeRealmsObservingCoverage();
624 
625   void startRecordingAllocations(double probability,
626                                  JS::RecordAllocationsCallback callback);
627   void stopRecordingAllocations();
628   void ensureRealmIsRecordingAllocations(JS::Handle<js::GlobalObject*> global);
629 
630   /* Locale-specific callbacks for string conversion. */
631   js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
632 
633   /* Default locale for Internationalization API */
634   js::MainThreadData<js::UniqueChars> defaultLocale;
635 
636   /* If true, new scripts must be created with PC counter information. */
637   js::MainThreadOrIonCompileData<bool> profilingScripts;
638 
639   /* Strong references on scripts held for PCCount profiling API. */
640   js::MainThreadData<JS::PersistentRooted<js::ScriptAndCountsVector>*>
641       scriptAndCountsVector;
642 
643  private:
644   /* Code coverage output. */
645   js::UnprotectedData<js::coverage::LCovRuntime> lcovOutput_;
646 
647  public:
lcovOutputJSRuntime648   js::coverage::LCovRuntime& lcovOutput() { return lcovOutput_.ref(); }
649 
650  private:
651   js::UnprotectedData<js::jit::JitRuntime*> jitRuntime_;
652 
653  public:
654   mozilla::Maybe<js::frontend::ScriptIndexRange> getSelfHostedScriptIndexRange(
655       js::PropertyName* name);
656 
657   [[nodiscard]] bool createJitRuntime(JSContext* cx);
jitRuntimeJSRuntime658   js::jit::JitRuntime* jitRuntime() const { return jitRuntime_.ref(); }
hasJitRuntimeJSRuntime659   bool hasJitRuntime() const { return !!jitRuntime_; }
660 
661  private:
662   // Used to generate random keys for hash tables.
663   mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG> randomKeyGenerator_;
664   mozilla::non_crypto::XorShift128PlusRNG& randomKeyGenerator();
665 
666   // Used to generate random hash codes for symbols.
667   mozilla::Maybe<mozilla::non_crypto::XorShift128PlusRNG>
668       randomHashCodeGenerator_;
669 
670  public:
671   mozilla::HashCodeScrambler randomHashCodeScrambler();
672   mozilla::non_crypto::XorShift128PlusRNG forkRandomKeyGenerator();
673 
674   js::HashNumber randomHashCode();
675 
676   //-------------------------------------------------------------------------
677   // Self-hosting support
678   //-------------------------------------------------------------------------
679 
hasInitializedSelfHostingJSRuntime680   bool hasInitializedSelfHosting() const { return hasSelfHostStencil(); }
681 
682   bool initSelfHostingStencil(JSContext* cx, JS::SelfHostedCache xdrCache,
683                               JS::SelfHostedWriter xdrWriter);
684   bool initSelfHostingFromStencil(JSContext* cx);
685   void finishSelfHosting();
686   void traceSelfHostingStencil(JSTracer* trc);
687   js::GeneratorKind getSelfHostedFunctionGeneratorKind(js::PropertyName* name);
688   bool delazifySelfHostedFunction(JSContext* cx,
689                                   js::Handle<js::PropertyName*> name,
690                                   js::Handle<JSFunction*> targetFun);
691   bool getSelfHostedValue(JSContext* cx, js::Handle<js::PropertyName*> name,
692                           js::MutableHandleValue vp);
693   void assertSelfHostedFunctionHasCanonicalName(js::HandlePropertyName name);
694 
695   //-------------------------------------------------------------------------
696   // Locale information
697   //-------------------------------------------------------------------------
698 
699   /*
700    * Set the default locale for the ECMAScript Internationalization API
701    * (Intl.Collator, Intl.NumberFormat, Intl.DateTimeFormat).
702    * Note that the Internationalization API encourages clients to
703    * specify their own locales.
704    * The locale string remains owned by the caller.
705    */
706   bool setDefaultLocale(const char* locale);
707 
708   /* Reset the default locale to OS defaults. */
709   void resetDefaultLocale();
710 
711   /* Gets current default locale. String remains owned by context. */
712   const char* getDefaultLocale();
713 
714   /* Garbage collector state. */
715   js::gc::GCRuntime gc;
716 
717   /* Garbage collector state has been successfully initialized. */
718   js::WriteOnceData<bool> gcInitialized;
719 
hasZealModeJSRuntime720   bool hasZealMode(js::gc::ZealMode mode) { return gc.hasZealMode(mode); }
721 
lockGCJSRuntime722   void lockGC() { gc.lockGC(); }
723 
unlockGCJSRuntime724   void unlockGC() { gc.unlockGC(); }
725 
726   js::WriteOnceData<js::PropertyName*> emptyString;
727 
728  private:
729   js::MainThreadOrGCTaskData<JSFreeOp*> defaultFreeOp_;
730 
731  public:
defaultFreeOpJSRuntime732   JSFreeOp* defaultFreeOp() {
733     MOZ_ASSERT(defaultFreeOp_);
734     return defaultFreeOp_;
735   }
736 
737 #if !JS_HAS_INTL_API
738   /* Number localization, used by jsnum.cpp. */
739   js::WriteOnceData<const char*> thousandsSeparator;
740   js::WriteOnceData<const char*> decimalSeparator;
741   js::WriteOnceData<const char*> numGrouping;
742 #endif
743 
744  private:
745   mozilla::Maybe<js::SharedImmutableStringsCache> sharedImmutableStrings_;
746 
747  public:
748   // If this particular JSRuntime has a SharedImmutableStringsCache, return a
749   // pointer to it, otherwise return nullptr.
maybeThisRuntimeSharedImmutableStringsJSRuntime750   js::SharedImmutableStringsCache* maybeThisRuntimeSharedImmutableStrings() {
751     return sharedImmutableStrings_.isSome() ? &*sharedImmutableStrings_
752                                             : nullptr;
753   }
754 
755   // Get a reference to this JSRuntime's or its parent's
756   // SharedImmutableStringsCache.
sharedImmutableStringsJSRuntime757   js::SharedImmutableStringsCache& sharedImmutableStrings() {
758     MOZ_ASSERT_IF(parentRuntime, !sharedImmutableStrings_);
759     MOZ_ASSERT_IF(!parentRuntime, sharedImmutableStrings_);
760     return parentRuntime ? parentRuntime->sharedImmutableStrings()
761                          : *sharedImmutableStrings_;
762   }
763 
764  private:
765   js::WriteOnceData<bool> beingDestroyed_;
766 
767  public:
isBeingDestroyedJSRuntime768   bool isBeingDestroyed() const { return beingDestroyed_; }
769 
770  private:
771   bool allowContentJS_;
772 
773  public:
allowContentJSJSRuntime774   bool allowContentJS() const { return allowContentJS_; }
775 
776   friend class js::AutoAssertNoContentJS;
777 
778  private:
779   // Table of all atoms other than those in permanentAtoms and staticStrings.
780   js::WriteOnceData<js::AtomsTable*> atoms_;
781 
782   // Set of all live symbols produced by Symbol.for(). All such symbols are
783   // allocated in the atoms zone. Reading or writing the symbol registry
784   // can only be done from the main thread.
785   js::MainThreadOrGCTaskData<js::SymbolRegistry> symbolRegistry_;
786 
787   js::WriteOnceData<js::FrozenAtomSet*> permanentAtoms_;
788 
789  public:
790   bool initializeAtoms(JSContext* cx);
791   bool initializeParserAtoms(JSContext* cx);
792   void finishAtoms();
793   void finishParserAtoms();
atomsAreFinishedJSRuntime794   bool atomsAreFinished() const { return !atoms_; }
795 
atomsForSweepingJSRuntime796   js::AtomsTable* atomsForSweeping() {
797     MOZ_ASSERT(JS::RuntimeHeapIsCollecting());
798     return atoms_;
799   }
800 
atomsJSRuntime801   js::AtomsTable& atoms() {
802     MOZ_ASSERT(atoms_);
803     return *atoms_;
804   }
805 
atomsZoneJSRuntime806   const JS::Zone* atomsZone() const {
807     MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this));
808     return gc.atomsZone;
809   }
atomsZoneJSRuntime810   JS::Zone* atomsZone() {
811     MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(this));
812     return gc.atomsZone;
813   }
unsafeAtomsZoneJSRuntime814   JS::Zone* unsafeAtomsZone() { return gc.atomsZone; }
815 
816 #ifdef DEBUG
isAtomsZoneJSRuntime817   bool isAtomsZone(const JS::Zone* zone) const { return zone == gc.atomsZone; }
818 #endif
819 
820   bool activeGCInAtomsZone();
821 
symbolRegistryJSRuntime822   js::SymbolRegistry& symbolRegistry() { return symbolRegistry_.ref(); }
823 
824   // Permanent atoms are fixed during initialization of the runtime and are
825   // not modified or collected until the runtime is destroyed. These may be
826   // shared with another, longer living runtime through |parentRuntime| and
827   // can be freely accessed with no locking necessary.
828 
829   // Permanent atoms pre-allocated for general use.
830   js::WriteOnceData<js::StaticStrings*> staticStrings;
831 
832   // Cached pointers to various permanent property names.
833   js::WriteOnceData<JSAtomState*> commonNames;
834   js::WriteOnceData<js::frontend::WellKnownParserAtoms*> commonParserNames;
835 
836   // All permanent atoms in the runtime, other than those in staticStrings.
837   // Access to this does not require a lock because it is frozen and thus
838   // read-only.
permanentAtomsJSRuntime839   const js::FrozenAtomSet* permanentAtoms() const {
840     MOZ_ASSERT(permanentAtomsPopulated());
841     return permanentAtoms_.ref();
842   }
843 
844   // The permanent atoms table is populated during initialization.
permanentAtomsPopulatedJSRuntime845   bool permanentAtomsPopulated() const { return permanentAtoms_; }
846 
847   // Cached well-known symbols (ES6 rev 24 6.1.5.1). Like permanent atoms,
848   // these are shared with the parentRuntime, if any.
849   js::WriteOnceData<js::WellKnownSymbols*> wellKnownSymbols;
850 
851 #ifdef JS_HAS_INTL_API
852   /* Shared Intl data for this runtime. */
853   js::MainThreadData<js::intl::SharedIntlData> sharedIntlData;
854 
855   void traceSharedIntlData(JSTracer* trc);
856 #endif
857 
858   // Table of bytecode and other data that may be shared across scripts
859   // within the runtime. This may be modified by threads using
860   // AutoLockScriptData.
861  private:
862   js::ScriptDataLockData<js::SharedImmutableScriptDataTable> scriptDataTable_;
863 
864  public:
scriptDataTableJSRuntime865   js::SharedImmutableScriptDataTable& scriptDataTable(
866       const js::AutoLockScriptData& lock) {
867     return scriptDataTable_.ref();
868   }
869 
870  private:
871   static mozilla::Atomic<size_t> liveRuntimesCount;
872 
873  public:
hasLiveRuntimesJSRuntime874   static bool hasLiveRuntimes() { return liveRuntimesCount > 0; }
875 
876   explicit JSRuntime(JSRuntime* parentRuntime);
877   ~JSRuntime();
878 
879   // destroyRuntime is used instead of a destructor, to ensure the downcast
880   // to JSContext remains valid. The final GC triggered here depends on this.
881   void destroyRuntime();
882 
883   bool init(JSContext* cx, uint32_t maxbytes);
884 
thisFromCtorJSRuntime885   JSRuntime* thisFromCtor() { return this; }
886 
887  private:
888   // Number of live SharedArrayBuffer objects, including those in Wasm shared
889   // memories.  uint64_t to avoid any risk of overflow.
890   js::MainThreadData<uint64_t> liveSABs;
891 
892  public:
incSABCountJSRuntime893   void incSABCount() {
894     MOZ_RELEASE_ASSERT(liveSABs != UINT64_MAX);
895     liveSABs++;
896   }
897 
decSABCountJSRuntime898   void decSABCount() {
899     MOZ_RELEASE_ASSERT(liveSABs > 0);
900     liveSABs--;
901   }
902 
hasLiveSABsJSRuntime903   bool hasLiveSABs() const { return liveSABs > 0; }
904 
905  public:
906   js::MainThreadData<JS::BeforeWaitCallback> beforeWaitCallback;
907   js::MainThreadData<JS::AfterWaitCallback> afterWaitCallback;
908 
909  public:
reportAllocationOverflowJSRuntime910   void reportAllocationOverflow() { js::ReportAllocationOverflow(nullptr); }
911 
912   /*
913    * This should be called after system malloc/calloc/realloc returns nullptr
914    * to try to recove some memory or to report an error.  For realloc, the
915    * original pointer must be passed as reallocPtr.
916    *
917    * The function must be called outside the GC lock.
918    */
919   JS_PUBLIC_API void* onOutOfMemory(js::AllocFunction allocator,
920                                     arena_id_t arena, size_t nbytes,
921                                     void* reallocPtr = nullptr,
922                                     JSContext* maybecx = nullptr);
923 
924   /*  onOutOfMemory but can call OnLargeAllocationFailure. */
925   JS_PUBLIC_API void* onOutOfMemoryCanGC(js::AllocFunction allocator,
926                                          arena_id_t arena, size_t nbytes,
927                                          void* reallocPtr = nullptr);
928 
929   static const unsigned LARGE_ALLOCATION = 25 * 1024 * 1024;
930 
931   void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
932                               JS::RuntimeSizes* rtSizes);
933 
934  private:
935   // Settings for how helper threads can be used.
936   mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
937       offthreadIonCompilationEnabled_;
938   mozilla::Atomic<bool, mozilla::SequentiallyConsistent>
939       parallelParsingEnabled_;
940 
941   js::MainThreadData<bool> autoWritableJitCodeActive_;
942 
943  public:
944   // Note: these values may be toggled dynamically (in response to about:config
945   // prefs changing).
setOffthreadIonCompilationEnabledJSRuntime946   void setOffthreadIonCompilationEnabled(bool value) {
947     offthreadIonCompilationEnabled_ = value;
948   }
canUseOffthreadIonCompilationJSRuntime949   bool canUseOffthreadIonCompilation() const {
950     return offthreadIonCompilationEnabled_;
951   }
setParallelParsingEnabledJSRuntime952   void setParallelParsingEnabled(bool value) {
953     parallelParsingEnabled_ = value;
954   }
canUseParallelParsingJSRuntime955   bool canUseParallelParsing() const { return parallelParsingEnabled_; }
956 
toggleAutoWritableJitCodeActiveJSRuntime957   void toggleAutoWritableJitCodeActive(bool b) {
958     MOZ_ASSERT(autoWritableJitCodeActive_ != b,
959                "AutoWritableJitCode should not be nested.");
960     autoWritableJitCodeActive_ = b;
961   }
962 
963   /* See comment for JS::SetOutOfMemoryCallback in js/MemoryCallbacks.h. */
964   js::MainThreadData<JS::OutOfMemoryCallback> oomCallback;
965   js::MainThreadData<void*> oomCallbackData;
966 
967   /*
968    * Debugger.Memory functions like takeCensus use this embedding-provided
969    * function to assess the size of malloc'd blocks of memory.
970    */
971   js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
972 
973   /* Last time at which an animation was played for this runtime. */
974   js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
975 
976  private:
977   /* The stack format for the current runtime.  Only valid on non-child
978    * runtimes. */
979   mozilla::Atomic<js::StackFormat, mozilla::ReleaseAcquire> stackFormat_;
980 
981  public:
stackFormatJSRuntime982   js::StackFormat stackFormat() const {
983     const JSRuntime* rt = this;
984     while (rt->parentRuntime) {
985       MOZ_ASSERT(rt->stackFormat_ == js::StackFormat::Default);
986       rt = rt->parentRuntime;
987     }
988     MOZ_ASSERT(rt->stackFormat_ != js::StackFormat::Default);
989     return rt->stackFormat_;
990   }
setStackFormatJSRuntime991   void setStackFormat(js::StackFormat format) {
992     MOZ_ASSERT(!parentRuntime);
993     MOZ_ASSERT(format != js::StackFormat::Default);
994     stackFormat_ = format;
995   }
996 
997  private:
998   js::MainThreadOrParseData<js::RuntimeCaches> caches_;
999 
1000  public:
cachesJSRuntime1001   js::RuntimeCaches& caches() { return caches_.ref(); }
1002 
1003   // List of all the live wasm::Instances in the runtime. Equal to the union
1004   // of all instances registered in all JS::Realms. Accessed from watchdog
1005   // threads for purposes of wasm::InterruptRunningCode().
1006   js::ExclusiveData<js::wasm::InstanceVector> wasmInstances;
1007 
1008   // The implementation-defined abstract operation HostResolveImportedModule.
1009   js::MainThreadData<JS::ModuleResolveHook> moduleResolveHook;
1010 
1011   // A hook that implements the abstract operations
1012   // HostGetImportMetaProperties and HostFinalizeImportMeta.
1013   js::MainThreadData<JS::ModuleMetadataHook> moduleMetadataHook;
1014 
1015   // A hook that implements the abstract operation
1016   // HostImportModuleDynamically. This is also used to enable/disable dynamic
1017   // module import and can accessed by off-thread parsing.
1018   mozilla::Atomic<JS::ModuleDynamicImportHook> moduleDynamicImportHook;
1019 
1020   // A hook that implements the abstract operation
1021   // HostGetSupportedImportAssertions.
1022   // https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions
1023   mozilla::Atomic<JS::SupportedAssertionsHook> supportedAssertionsHook;
1024 
1025   // Hooks called when script private references are created and destroyed.
1026   js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateAddRefHook;
1027   js::MainThreadData<JS::ScriptPrivateReferenceHook> scriptPrivateReleaseHook;
1028 
addRefScriptPrivateJSRuntime1029   void addRefScriptPrivate(const JS::Value& value) {
1030     if (!value.isUndefined() && scriptPrivateAddRefHook) {
1031       scriptPrivateAddRefHook(value);
1032     }
1033   }
1034 
releaseScriptPrivateJSRuntime1035   void releaseScriptPrivate(const JS::Value& value) {
1036     if (!value.isUndefined() && scriptPrivateReleaseHook) {
1037       scriptPrivateReleaseHook(value);
1038     }
1039   }
1040 
1041  public:
1042 #if defined(NIGHTLY_BUILD)
1043   // Support for informing the embedding of any error thrown.
1044   // This mechanism is designed to let the embedding
1045   // log/report/fail in case certain errors are thrown
1046   // (e.g. SyntaxError, ReferenceError or TypeError
1047   // in critical code).
1048   struct ErrorInterceptionSupport {
ErrorInterceptionSupportJSRuntime::ErrorInterceptionSupport1049     ErrorInterceptionSupport() : isExecuting(false), interceptor(nullptr) {}
1050 
1051     // true if the error interceptor is currently executing,
1052     // false otherwise. Used to avoid infinite loops.
1053     bool isExecuting;
1054 
1055     // if non-null, any call to `setPendingException`
1056     // in this runtime will trigger the call to `interceptor`
1057     JSErrorInterceptor* interceptor;
1058   };
1059   ErrorInterceptionSupport errorInterception;
1060 #endif  // defined(NIGHTLY_BUILD)
1061 };
1062 
1063 // Context for sending telemetry to the embedder from any thread, main or
1064 // helper.  Obtain a |JSTelemetrySender| by calling |getTelemetrySender()| on
1065 // the |JSRuntime|.
1066 struct JSTelemetrySender {
1067  private:
1068   friend struct JSRuntime;
1069 
1070   JSAccumulateTelemetryDataCallback callback_;
1071 
JSTelemetrySenderJSTelemetrySender1072   explicit JSTelemetrySender(JSAccumulateTelemetryDataCallback callback)
1073       : callback_(callback) {}
1074 
1075  public:
JSTelemetrySenderJSTelemetrySender1076   JSTelemetrySender() : callback_(nullptr) {}
1077   JSTelemetrySender(const JSTelemetrySender& other) = default;
JSTelemetrySenderJSTelemetrySender1078   explicit JSTelemetrySender(JSRuntime* runtime)
1079       : JSTelemetrySender(runtime->getTelemetrySender()) {}
1080 
1081   // Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
1082   // histogram. |key| provides an additional key to identify the histogram.
1083   // |sample| is the data to add to the histogram.
1084   void addTelemetry(int id, uint32_t sample, const char* key = nullptr) {
1085     if (callback_) {
1086       callback_(id, sample, key);
1087     }
1088   }
1089 };
1090 
1091 namespace js {
1092 
MakeRangeGCSafe(Value * vec,size_t len)1093 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* vec, size_t len) {
1094   // Don't PodZero here because JS::Value is non-trivial.
1095   for (size_t i = 0; i < len; i++) {
1096     vec[i].setDouble(+0.0);
1097   }
1098 }
1099 
MakeRangeGCSafe(Value * beg,Value * end)1100 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Value* beg, Value* end) {
1101   MakeRangeGCSafe(beg, end - beg);
1102 }
1103 
MakeRangeGCSafe(jsid * beg,jsid * end)1104 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* beg, jsid* end) {
1105   std::fill(beg, end, PropertyKey::Int(0));
1106 }
1107 
MakeRangeGCSafe(jsid * vec,size_t len)1108 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(jsid* vec, size_t len) {
1109   MakeRangeGCSafe(vec, vec + len);
1110 }
1111 
MakeRangeGCSafe(Shape ** beg,Shape ** end)1112 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** beg, Shape** end) {
1113   std::fill(beg, end, nullptr);
1114 }
1115 
MakeRangeGCSafe(Shape ** vec,size_t len)1116 static MOZ_ALWAYS_INLINE void MakeRangeGCSafe(Shape** vec, size_t len) {
1117   MakeRangeGCSafe(vec, vec + len);
1118 }
1119 
SetValueRangeToUndefined(Value * beg,Value * end)1120 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* beg, Value* end) {
1121   for (Value* v = beg; v != end; ++v) {
1122     v->setUndefined();
1123   }
1124 }
1125 
SetValueRangeToUndefined(Value * vec,size_t len)1126 static MOZ_ALWAYS_INLINE void SetValueRangeToUndefined(Value* vec, size_t len) {
1127   SetValueRangeToUndefined(vec, vec + len);
1128 }
1129 
SetValueRangeToNull(Value * beg,Value * end)1130 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* beg, Value* end) {
1131   for (Value* v = beg; v != end; ++v) {
1132     v->setNull();
1133   }
1134 }
1135 
SetValueRangeToNull(Value * vec,size_t len)1136 static MOZ_ALWAYS_INLINE void SetValueRangeToNull(Value* vec, size_t len) {
1137   SetValueRangeToNull(vec, vec + len);
1138 }
1139 
1140 extern const JSSecurityCallbacks NullSecurityCallbacks;
1141 
1142 // This callback is set by JS::SetProcessLargeAllocationFailureCallback
1143 // and may be null. See comment in jsapi.h.
1144 extern mozilla::Atomic<JS::LargeAllocationFailureCallback>
1145     OnLargeAllocationFailure;
1146 
1147 // This callback is set by JS::SetBuildIdOp and may be null. See comment in
1148 // jsapi.h.
1149 extern mozilla::Atomic<JS::BuildIdOp> GetBuildId;
1150 
1151 extern JS::FilenameValidationCallback gFilenameValidationCallback;
1152 
1153 } /* namespace js */
1154 
1155 #endif /* vm_Runtime_h */
1156