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