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/. */
12 #include "js/CallArgs.h"
14 #include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
16 #include "js/HeapAPI.h"
17 #include "js/Object.h" // JS::GetClass
18 #include "js/shadow/Function.h" // JS::shadow::Function
19 #include "js/shadow/Object.h" // JS::shadow::Object
20 #include "js/TypeDecls.h"
25 * Set a callback used to trace gray roots.
27 * The callback is called after the first slice of GC so the embedding must
28 * implement appropriate barriers on its gray roots to ensure correctness.
30 * This callback may be called multiple times for different sets of zones. Use
31 * JS::ZoneIsGrayMarking() to determine whether roots from a particular zone are
34 extern JS_PUBLIC_API
void JS_SetGrayGCRootsTracer(JSContext
* cx
,
35 JSGrayRootsTracer traceOp
,
38 extern JS_PUBLIC_API JSObject
* JS_FindCompilationScope(JSContext
* cx
,
39 JS::HandleObject obj
);
41 extern JS_PUBLIC_API JSFunction
* JS_GetObjectFunction(JSObject
* obj
);
44 * Allocate an object in exactly the same way as JS_NewObjectWithGivenProto, but
45 * without invoking the metadata callback on it. This allows creation of
46 * internal bookkeeping objects that are guaranteed to not have metadata
49 extern JS_PUBLIC_API JSObject
* JS_NewObjectWithoutMetadata(
50 JSContext
* cx
, const JSClass
* clasp
, JS::Handle
<JSObject
*> proto
);
52 extern JS_PUBLIC_API
bool JS_NondeterministicGetWeakMapKeys(
53 JSContext
* cx
, JS::HandleObject obj
, JS::MutableHandleObject ret
);
55 extern JS_PUBLIC_API
bool JS_NondeterministicGetWeakSetKeys(
56 JSContext
* cx
, JS::HandleObject obj
, JS::MutableHandleObject ret
);
58 // Raw JSScript* because this needs to be callable from a signal handler.
59 extern JS_PUBLIC_API
unsigned JS_PCToLineNumber(
60 JSScript
* script
, jsbytecode
* pc
,
61 JS::LimitedColumnNumberOneOrigin
* columnp
= nullptr);
64 * Determine whether the given object is backed by a DeadObjectProxy.
66 * Such objects hold no other objects (they have no outgoing reference edges)
67 * and will throw if you touch them (e.g. by reading/writing a property).
69 extern JS_PUBLIC_API
bool JS_IsDeadWrapper(JSObject
* obj
);
72 * Creates a new dead wrapper object in the given scope. To be used when
73 * attempting to wrap objects from scopes which are already dead.
75 * If origObject is passed, it must be an proxy object, and will be
76 * used to determine the characteristics of the new dead wrapper.
78 extern JS_PUBLIC_API JSObject
* JS_NewDeadWrapper(
79 JSContext
* cx
, JSObject
* origObject
= nullptr);
84 * Get the script private value associated with an object, if any.
86 * The private value is set with SetScriptPrivate() or SetModulePrivate() and is
87 * internally stored on the relevant ScriptSourceObject.
89 * This is used by the cycle collector to trace through
90 * ScriptSourceObjects. This allows private values to contain an nsISupports
91 * pointer and hence support references to cycle collected C++ objects.
93 JS_PUBLIC_API
JS::Value
MaybeGetScriptPrivate(JSObject
* object
);
98 * Used by the cycle collector to trace through a shape or object group and
99 * all cycle-participating data it reaches, using bounded stack space.
101 extern JS_PUBLIC_API
void JS_TraceShapeCycleCollectorChildren(
102 JS::CallbackTracer
* trc
, JS::GCCellPtr shape
);
103 extern JS_PUBLIC_API
void JS_TraceObjectGroupCycleCollectorChildren(
104 JS::CallbackTracer
* trc
, JS::GCCellPtr group
);
106 extern JS_PUBLIC_API JSPrincipals
* JS_GetScriptPrincipals(JSScript
* script
);
108 extern JS_PUBLIC_API
bool JS_ScriptHasMutedErrors(JSScript
* script
);
110 extern JS_PUBLIC_API JSObject
* JS_CloneObject(JSContext
* cx
,
111 JS::HandleObject obj
,
112 JS::HandleObject proto
);
115 * Copy the own properties of src to dst in a fast way. src and dst must both
116 * be native and must be in the compartment of cx. They must have the same
117 * class, the same parent, and the same prototype. Class reserved slots will
120 * dst must not have any properties on it before this function is called.
122 * src must have been allocated via JS_NewObjectWithoutMetadata so that we can
123 * be sure it has no metadata that needs copying to dst. This also means that
124 * dst needs to have the compartment global as its parent. This function will
125 * preserve the existing metadata on dst, if any.
127 extern JS_PUBLIC_API
bool JS_InitializePropertiesFromCompatibleNativeObject(
128 JSContext
* cx
, JS::HandleObject dst
, JS::HandleObject src
);
132 JS_PUBLIC_API
bool IsArgumentsObject(JS::HandleObject obj
);
134 JS_PUBLIC_API
bool AddRawValueRoot(JSContext
* cx
, JS::Value
* vp
,
137 JS_PUBLIC_API
void RemoveRawValueRoot(JSContext
* cx
, JS::Value
* vp
);
144 * Set all of the uninitialized lexicals on an object to undefined. Return
145 * true if any lexicals were initialized and false otherwise.
147 extern JS_PUBLIC_API
bool ForceLexicalInitialization(JSContext
* cx
,
151 * Whether we are poisoning unused/released data for error detection. Governed
152 * by the JS_GC_ALLOW_EXTRA_POISONING #ifdef as well as the
153 * $JSGC_EXTRA_POISONING environment variable.
155 extern JS_PUBLIC_API
int IsGCPoisoning();
157 extern JS_PUBLIC_API JSPrincipals
* GetRealmPrincipals(JS::Realm
* realm
);
159 extern JS_PUBLIC_API
void SetRealmPrincipals(JS::Realm
* realm
,
160 JSPrincipals
* principals
);
162 extern JS_PUBLIC_API
bool GetIsSecureContext(JS::Realm
* realm
);
164 extern JS_PUBLIC_API
bool GetDebuggerObservesWasm(JS::Realm
* realm
);
169 * Copies all own properties and private fields from |obj| to |target|. Both
170 * |obj| and |target| must not be cross-compartment wrappers because we have to
171 * enter their realms.
173 * This function immediately enters a realm, and does not impose any
174 * restrictions on the realm of |cx|.
176 extern JS_PUBLIC_API
bool JS_CopyOwnPropertiesAndPrivateFields(
177 JSContext
* cx
, JS::HandleObject target
, JS::HandleObject obj
);
179 extern JS_PUBLIC_API
bool JS_WrapPropertyDescriptor(
180 JSContext
* cx
, JS::MutableHandle
<JS::PropertyDescriptor
> desc
);
182 extern JS_PUBLIC_API
bool JS_WrapPropertyDescriptor(
184 JS::MutableHandle
<mozilla::Maybe
<JS::PropertyDescriptor
>> desc
);
186 struct JSFunctionSpecWithHelp
{
191 const JSJitInfo
* jitInfo
;
196 #define JS_FN_HELP(name, call, nargs, flags, usage, help) \
197 { name, call, nargs, (flags) | JSPROP_ENUMERATE, nullptr, usage, help }
198 #define JS_INLINABLE_FN_HELP(name, call, nargs, flags, native, usage, help) \
200 name, call, nargs, (flags) | JSPROP_ENUMERATE, &js::jit::JitInfo_##native, \
203 #define JS_FS_HELP_END \
204 { nullptr, nullptr, 0, 0, nullptr, nullptr }
206 extern JS_PUBLIC_API
bool JS_DefineFunctionsWithHelp(
207 JSContext
* cx
, JS::HandleObject obj
, const JSFunctionSpecWithHelp
* fs
);
212 * Use the runtime's internal handling of job queues for Promise jobs.
214 * Most embeddings, notably web browsers, will have their own task scheduling
215 * systems and need to integrate handling of Promise jobs into that, so they
216 * will want to manage job queues themselves. For basic embeddings such as the
217 * JS shell that don't have an event loop of their own, it's easier to have
218 * SpiderMonkey handle job queues internally.
220 * Note that the embedding still has to trigger processing of job queues at
221 * right time(s), such as after evaluation of a script has run to completion.
223 extern JS_PUBLIC_API
bool UseInternalJobQueues(JSContext
* cx
);
227 * Given internal job queues are used, return currently queued jobs as an
228 * array of job objects.
230 extern JS_PUBLIC_API JSObject
* GetJobsInInternalJobQueue(JSContext
* cx
);
234 * Enqueue |job| on the internal job queue.
236 * This is useful in tests for creating situations where a call occurs with no
237 * other JavaScript on the stack.
239 extern JS_PUBLIC_API
bool EnqueueJob(JSContext
* cx
, JS::HandleObject job
);
242 * Instruct the runtime to stop draining the internal job queue.
244 * Useful if the embedding is in the process of quitting in reaction to a
245 * builtin being called, or if it wants to resume executing jobs later on.
247 extern JS_PUBLIC_API
void StopDrainingJobQueue(JSContext
* cx
);
249 extern JS_PUBLIC_API
void RunJobs(JSContext
* cx
);
251 extern JS_PUBLIC_API
JS::Zone
* GetRealmZone(JS::Realm
* realm
);
253 using PreserveWrapperCallback
= bool (*)(JSContext
*, JS::HandleObject
);
254 using HasReleasedWrapperCallback
= bool (*)(JS::HandleObject
);
256 extern JS_PUBLIC_API
bool IsSystemRealm(JS::Realm
* realm
);
258 extern JS_PUBLIC_API
bool IsSystemCompartment(JS::Compartment
* comp
);
260 extern JS_PUBLIC_API
bool IsSystemZone(JS::Zone
* zone
);
262 struct WeakMapTracer
{
265 explicit WeakMapTracer(JSRuntime
* rt
) : runtime(rt
) {}
267 // Weak map tracer callback, called once for every binding of every
268 // weak map that was live at the time of the last garbage collection.
270 // m will be nullptr if the weak map is not contained in a JS Object.
272 // The callback should not GC (and will assert in a debug build if it does
274 virtual void trace(JSObject
* m
, JS::GCCellPtr key
, JS::GCCellPtr value
) = 0;
277 extern JS_PUBLIC_API
void TraceWeakMaps(WeakMapTracer
* trc
);
279 extern JS_PUBLIC_API
bool AreGCGrayBitsValid(JSRuntime
* rt
);
281 extern JS_PUBLIC_API
bool ZoneGlobalsAreAllGray(JS::Zone
* zone
);
283 extern JS_PUBLIC_API
bool IsCompartmentZoneSweepingOrCompacting(
284 JS::Compartment
* comp
);
286 using IterateGCThingCallback
= void (*)(void*, JS::GCCellPtr
,
287 const JS::AutoRequireNoGC
&);
289 extern JS_PUBLIC_API
void TraceGrayWrapperTargets(JSTracer
* trc
,
293 * Invoke cellCallback on every gray JSObject in the given zone.
295 extern JS_PUBLIC_API
void IterateGrayObjects(
296 JS::Zone
* zone
, IterateGCThingCallback cellCallback
, void* data
);
298 #if defined(JS_GC_ZEAL) || defined(DEBUG)
299 // Trace the heap and check there are no black to gray edges. These are
300 // not allowed since the cycle collector could throw away the gray thing and
301 // leave a dangling pointer.
303 // This doesn't trace weak maps as these are handled separately.
304 extern JS_PUBLIC_API
bool CheckGrayMarkingState(JSRuntime
* rt
);
307 // Note: this returns nullptr iff |zone| is the atoms zone.
308 extern JS_PUBLIC_API
JS::Realm
* GetAnyRealmInZone(JS::Zone
* zone
);
310 // Returns the first realm's global in a compartment. Note: this is not
311 // guaranteed to always be the same realm because individual realms can be
312 // collected by the GC.
313 extern JS_PUBLIC_API JSObject
* GetFirstGlobalInCompartment(
314 JS::Compartment
* comp
);
316 // Returns true if the compartment contains a global object and this global is
317 // not being collected.
318 extern JS_PUBLIC_API
bool CompartmentHasLiveGlobal(JS::Compartment
* comp
);
320 // Returns true if this compartment can be shared across multiple Realms. Used
321 // when we're looking for an existing compartment to place a new Realm in.
322 extern JS_PUBLIC_API
bool IsSharableCompartment(JS::Compartment
* comp
);
324 // This is equal to |&JSObject::class_|. Use it in places where you don't want
325 // to #include vm/JSObject.h.
326 extern JS_PUBLIC_DATA
const JSClass
* const ObjectClassPtr
;
328 JS_PUBLIC_API
const JSClass
* ProtoKeyToClass(JSProtoKey key
);
330 // Returns the key for the class inherited by a given standard class (that
331 // is to say, the prototype of this standard class's prototype).
333 // You must be sure that this corresponds to a standard class with a cached
334 // JSProtoKey before calling this function. In general |key| will match the
335 // cached proto key, except in cases where multiple JSProtoKeys share a
337 inline JSProtoKey
InheritanceProtoKeyForStandardClass(JSProtoKey key
) {
338 // [Object] has nothing to inherit from.
339 if (key
== JSProto_Object
) {
343 // If we're ClassSpec defined return the proto key from that
344 if (ProtoKeyToClass(key
)->specDefined()) {
345 return ProtoKeyToClass(key
)->specInheritanceProtoKey();
348 // Otherwise, we inherit [Object].
349 return JSProto_Object
;
352 JS_PUBLIC_API
bool ShouldIgnorePropertyDefinition(JSContext
* cx
, JSProtoKey key
,
355 JS_PUBLIC_API
bool IsFunctionObject(JSObject
* obj
);
357 JS_PUBLIC_API
bool UninlinedIsCrossCompartmentWrapper(const JSObject
* obj
);
359 // CrossCompartmentWrappers are shared by all realms within the compartment, so
360 // getting a wrapper's realm usually doesn't make sense.
361 static MOZ_ALWAYS_INLINE
JS::Realm
* GetNonCCWObjectRealm(JSObject
* obj
) {
362 MOZ_ASSERT(!js::UninlinedIsCrossCompartmentWrapper(obj
));
363 return reinterpret_cast<JS::shadow::Object
*>(obj
)->shape
->base
->realm
;
366 JS_PUBLIC_API
void AssertSameCompartment(JSContext
* cx
, JSObject
* obj
);
368 JS_PUBLIC_API
void AssertSameCompartment(JSContext
* cx
, JS::HandleValue v
);
371 JS_PUBLIC_API
void AssertSameCompartment(JSObject
* objA
, JSObject
* objB
);
373 inline void AssertSameCompartment(JSObject
* objA
, JSObject
* objB
) {}
376 JS_PUBLIC_API
void NotifyAnimationActivity(JSObject
* obj
);
378 JS_PUBLIC_API JSFunction
* DefineFunctionWithReserved(
379 JSContext
* cx
, JSObject
* obj
, const char* name
, JSNative call
,
380 unsigned nargs
, unsigned attrs
);
382 JS_PUBLIC_API JSFunction
* NewFunctionWithReserved(JSContext
* cx
, JSNative call
,
387 JS_PUBLIC_API JSFunction
* NewFunctionByIdWithReserved(JSContext
* cx
,
390 unsigned flags
, jsid id
);
393 * Get or set function's reserved slot value.
394 * `fun` should be a function created with `*WithReserved` API above.
395 * Such functions have 2 reserved slots, and `which` can be either 0 or 1.
397 JS_PUBLIC_API
const JS::Value
& GetFunctionNativeReserved(JSObject
* fun
,
400 JS_PUBLIC_API
void SetFunctionNativeReserved(JSObject
* fun
, size_t which
,
401 const JS::Value
& val
);
403 JS_PUBLIC_API
bool FunctionHasNativeReserved(JSObject
* fun
);
405 JS_PUBLIC_API
bool GetObjectProto(JSContext
* cx
, JS::HandleObject obj
,
406 JS::MutableHandleObject proto
);
408 extern JS_PUBLIC_API JSObject
* GetStaticPrototype(JSObject
* obj
);
410 JS_PUBLIC_API
bool GetRealmOriginalEval(JSContext
* cx
,
411 JS::MutableHandleObject eval
);
414 * Add some or all property keys of obj to the id vector *props.
416 * The flags parameter controls which property keys are added. Pass a
417 * combination of the following bits:
419 * JSITER_OWNONLY - Don't also search the prototype chain; only consider
420 * obj's own properties.
422 * JSITER_HIDDEN - Include nonenumerable properties.
424 * JSITER_SYMBOLS - Include property keys that are symbols. The default
425 * behavior is to filter out symbols.
427 * JSITER_SYMBOLSONLY - Exclude non-symbol property keys.
429 * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or
430 * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass
431 * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get
432 * results that match the output of Reflect.ownKeys.
434 JS_PUBLIC_API
bool GetPropertyKeys(JSContext
* cx
, JS::HandleObject obj
,
436 JS::MutableHandleIdVector props
);
438 JS_PUBLIC_API
bool AppendUnique(JSContext
* cx
, JS::MutableHandleIdVector base
,
439 JS::HandleIdVector others
);
442 * Determine whether the given string is an array index in the sense of
443 * <https://tc39.github.io/ecma262/#array-index>.
445 * If it isn't, returns false.
447 * If it is, returns true and outputs the index in *indexp.
449 JS_PUBLIC_API
bool StringIsArrayIndex(JSLinearString
* str
, uint32_t* indexp
);
452 * Overload of StringIsArrayIndex taking a (char16_t*,length) pair. Behaves
453 * the same as the JSLinearString version.
455 JS_PUBLIC_API
bool StringIsArrayIndex(const char16_t
* str
, uint32_t length
,
458 JS_PUBLIC_API
void SetPreserveWrapperCallbacks(
459 JSContext
* cx
, PreserveWrapperCallback preserveWrapper
,
460 HasReleasedWrapperCallback hasReleasedWrapper
);
462 JS_PUBLIC_API
bool IsObjectInContextCompartment(JSObject
* obj
,
463 const JSContext
* cx
);
466 * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
468 /* 0x1 is no longer used */
469 /* 0x2 is no longer used */
470 #define JSITER_PRIVATE 0x4 /* Include private names in iteration */
471 #define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
472 #define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
473 #define JSITER_SYMBOLS 0x20 /* also include symbol property keys */
474 #define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
475 #define JSITER_FORAWAITOF 0x80 /* for-await-of */
477 using DOMInstanceClassHasProtoAtDepth
= bool (*)(const JSClass
*, uint32_t,
479 struct JSDOMCallbacks
{
480 DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto
;
482 using DOMCallbacks
= struct JSDOMCallbacks
;
484 extern JS_PUBLIC_API
void SetDOMCallbacks(JSContext
* cx
,
485 const DOMCallbacks
* callbacks
);
487 extern JS_PUBLIC_API
const DOMCallbacks
* GetDOMCallbacks(JSContext
* cx
);
489 extern JS_PUBLIC_API JSObject
* GetTestingFunctions(JSContext
* cx
);
491 /* Implemented in jsexn.cpp. */
494 * Get an error type name from a JSExnType constant.
495 * Returns nullptr for invalid arguments and JSEXN_INTERNALERR
497 extern JS_PUBLIC_API JSLinearString
* GetErrorTypeName(JSContext
* cx
,
500 /* Implemented in CrossCompartmentWrapper.cpp. */
501 typedef enum NukeReferencesToWindow
{
502 NukeWindowReferences
,
503 DontNukeWindowReferences
504 } NukeReferencesToWindow
;
506 typedef enum NukeReferencesFromTarget
{
508 NukeIncomingReferences
,
509 } NukeReferencesFromTarget
;
512 * These filters are designed to be ephemeral stack classes, and thus don't
513 * do any rooting or holding of their members.
515 struct CompartmentFilter
{
516 virtual bool match(JS::Compartment
* c
) const = 0;
519 struct AllCompartments
: public CompartmentFilter
{
520 virtual bool match(JS::Compartment
* c
) const override
{ return true; }
523 struct SingleCompartment
: public CompartmentFilter
{
524 JS::Compartment
* ours
;
525 explicit SingleCompartment(JS::Compartment
* c
) : ours(c
) {}
526 virtual bool match(JS::Compartment
* c
) const override
{ return c
== ours
; }
529 extern JS_PUBLIC_API
bool NukeCrossCompartmentWrappers(
530 JSContext
* cx
, const CompartmentFilter
& sourceFilter
, JS::Realm
* target
,
531 NukeReferencesToWindow nukeReferencesToWindow
,
532 NukeReferencesFromTarget nukeReferencesFromTarget
);
534 extern JS_PUBLIC_API
bool AllowNewWrapper(JS::Compartment
* target
,
537 extern JS_PUBLIC_API
bool NukedObjectRealm(JSObject
* obj
);
539 /* Implemented in jsdate.cpp. */
541 /** Detect whether the internal date value is NaN. */
542 extern JS_PUBLIC_API
bool DateIsValid(JSContext
* cx
, JS::HandleObject obj
,
545 extern JS_PUBLIC_API
bool DateGetMsecSinceEpoch(JSContext
* cx
,
546 JS::HandleObject obj
,
547 double* msecSinceEpoch
);
553 /* Implemented in vm/StructuredClone.cpp. */
554 extern JS_PUBLIC_API
uint64_t GetSCOffset(JSStructuredCloneWriter
* writer
);
560 /* Statically asserted in FunctionFlags.cpp. */
561 static const unsigned JS_FUNCTION_INTERPRETED_BITS
= 0x0060;
565 static MOZ_ALWAYS_INLINE
const JSJitInfo
* FUNCTION_VALUE_TO_JITINFO(
566 const JS::Value
& v
) {
567 JSObject
* obj
= &v
.toObject();
568 MOZ_ASSERT(JS::GetClass(obj
)->isJSFunction());
570 auto* fun
= reinterpret_cast<JS::shadow::Function
*>(obj
);
571 MOZ_ASSERT(!(fun
->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS
),
572 "Unexpected non-native function");
574 return static_cast<const JSJitInfo
*>(fun
->jitInfoOrScript());
577 static MOZ_ALWAYS_INLINE
void SET_JITINFO(JSFunction
* func
,
578 const JSJitInfo
* info
) {
579 auto* fun
= reinterpret_cast<JS::shadow::Function
*>(func
);
580 MOZ_ASSERT(!(fun
->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS
));
582 fun
->setJitInfoOrScript(const_cast<JSJitInfo
*>(info
));
585 static_assert(sizeof(jsid
) == sizeof(void*));
589 static MOZ_ALWAYS_INLINE
JS::Value
IdToValue(jsid id
) {
591 return JS::StringValue(id
.toString());
594 return JS::Int32Value(id
.toInt());
597 return JS::SymbolValue(id
.toSymbol());
599 MOZ_ASSERT(id
.isVoid());
600 return JS::UndefinedValue();
604 * PrepareScriptEnvironmentAndInvoke asserts the embedder has registered a
605 * ScriptEnvironmentPreparer and then it calls the preparer's 'invoke' method
606 * with the given |closure|, with the assumption that the preparer will set up
607 * any state necessary to run script in |global|, invoke |closure| with a valid
608 * JSContext*, report any exceptions thrown from the closure, and return.
610 * PrepareScriptEnvironmentAndInvoke will report any exceptions that are thrown
611 * by the closure. Consumers who want to propagate back whether the closure
612 * succeeded should do so via members of the closure itself.
615 struct ScriptEnvironmentPreparer
{
617 virtual bool operator()(JSContext
* cx
) = 0;
620 virtual void invoke(JS::HandleObject global
, Closure
& closure
) = 0;
623 extern JS_PUBLIC_API
void PrepareScriptEnvironmentAndInvoke(
624 JSContext
* cx
, JS::HandleObject global
,
625 ScriptEnvironmentPreparer::Closure
& closure
);
627 JS_PUBLIC_API
void SetScriptEnvironmentPreparer(
628 JSContext
* cx
, ScriptEnvironmentPreparer
* preparer
);
630 // Abstract base class for objects that build allocation metadata for JavaScript
632 struct AllocationMetadataBuilder
{
633 AllocationMetadataBuilder() = default;
635 // Return a metadata object for the newly constructed object |obj|, or
636 // nullptr if there's no metadata to attach.
638 // Implementations should treat all errors as fatal; there is no way to
639 // report errors from this callback. In particular, the caller provides an
640 // oomUnsafe for overriding implementations to use.
641 virtual JSObject
* build(JSContext
* cx
, JS::HandleObject obj
,
642 AutoEnterOOMUnsafeRegion
& oomUnsafe
) const {
648 * Specify a callback to invoke when creating each JS object in the current
649 * compartment, which may return a metadata object to associate with the
652 JS_PUBLIC_API
void SetAllocationMetadataBuilder(
653 JSContext
* cx
, const AllocationMetadataBuilder
* callback
);
655 /** Get the metadata associated with an object. */
656 JS_PUBLIC_API JSObject
* GetAllocationMetadata(JSObject
* obj
);
658 JS_PUBLIC_API
bool GetElementsWithAdder(JSContext
* cx
, JS::HandleObject obj
,
659 JS::HandleObject receiver
,
660 uint32_t begin
, uint32_t end
,
661 js::ElementAdder
* adder
);
663 JS_PUBLIC_API
bool ForwardToNative(JSContext
* cx
, JSNative native
,
664 const JS::CallArgs
& args
);
667 * Helper function for HTMLDocument and HTMLFormElement.
669 * These are the only two interfaces that have [OverrideBuiltins], a named
670 * getter, and no named setter. They're implemented as proxies with a custom
671 * getOwnPropertyDescriptor() method. Unfortunately, overriding
672 * getOwnPropertyDescriptor() automatically affects the behavior of set(),
673 * which normally is just common sense but is *not* desired for these two
676 * The fix is for these two interfaces to override set() to ignore the
677 * getOwnPropertyDescriptor() override.
679 * SetPropertyIgnoringNamedGetter is exposed to make it easier to override
680 * set() in this way. It carries out all the steps of BaseProxyHandler::set()
681 * except the initial getOwnPropertyDescriptor() call. The caller must supply
682 * that descriptor as the 'ownDesc' parameter.
684 * Implemented in proxy/BaseProxyHandler.cpp.
686 JS_PUBLIC_API
bool SetPropertyIgnoringNamedGetter(
687 JSContext
* cx
, JS::HandleObject obj
, JS::HandleId id
, JS::HandleValue v
,
688 JS::HandleValue receiver
,
689 JS::Handle
<mozilla::Maybe
<JS::PropertyDescriptor
>> ownDesc
,
690 JS::ObjectOpResult
& result
);
692 // This function is for one specific use case, please don't use this for
694 extern JS_PUBLIC_API
bool ExecuteInFrameScriptEnvironment(
695 JSContext
* cx
, JS::HandleObject obj
, JS::HandleScript script
,
696 JS::MutableHandleObject scope
);
698 extern JS_PUBLIC_API
bool IsSavedFrame(JSObject
* obj
);
700 // Matches the condition in js/src/jit/ProcessExecutableMemory.cpp
702 // Parameters use void* types to avoid #including windows.h. The return value of
703 // this function is returned from the exception handler.
704 typedef long (*JitExceptionHandler
)(void* exceptionRecord
, // PEXECTION_RECORD
705 void* context
); // PCONTEXT
708 * Windows uses "structured exception handling" to handle faults. When a fault
709 * occurs, the stack is searched for a handler (similar to C++ exception
710 * handling). If the search does not find a handler, the "unhandled exception
711 * filter" is called. Breakpad uses the unhandled exception filter to do crash
712 * reporting. Unfortunately, on Win64, JIT code on the stack completely throws
713 * off this unwinding process and prevents the unhandled exception filter from
714 * being called. The reason is that Win64 requires unwind information be
715 * registered for all code regions and JIT code has none. While it is possible
716 * to register full unwind information for JIT code, this is a lot of work (one
717 * has to be able to recover the frame pointer at any PC) so instead we register
718 * a handler for all JIT code that simply calls breakpad's unhandled exception
719 * filter (which will perform crash reporting and then terminate the process).
720 * This would be wrong if there was an outer __try block that expected to handle
721 * the fault, but this is not generally allowed.
723 * Gecko must call SetJitExceptionFilter before any JIT code is compiled and
724 * only once per process.
726 extern JS_PUBLIC_API
void SetJitExceptionHandler(JitExceptionHandler handler
);
729 extern JS_PUBLIC_API
bool ReportIsNotFunction(JSContext
* cx
, JS::HandleValue v
);
731 class MOZ_STACK_CLASS JS_PUBLIC_API AutoAssertNoContentJS
{
733 explicit AutoAssertNoContentJS(JSContext
* cx
);
734 ~AutoAssertNoContentJS();
738 bool prevAllowContentJS_
;
742 * This function reports memory used by a zone in bytes, this includes:
743 * * The size of this JS GC zone.
744 * * Malloc memory referred to from this zone.
745 * * JIT memory for this zone.
747 * Note that malloc memory referred to from this zone can include
748 * SharedArrayBuffers which may also be referred to from other zones. Adding the
749 * memory usage of multiple zones may lead to an over-estimate.
751 extern JS_PUBLIC_API
uint64_t GetMemoryUsageForZone(JS::Zone
* zone
);
753 enum class MemoryUse
: uint8_t;
757 struct SharedMemoryUse
{
758 explicit SharedMemoryUse(MemoryUse use
) : count(0), nbytes(0) {
771 // A map which tracks shared memory uses (shared in the sense that an allocation
772 // can be referenced by more than one GC thing in a zone). This allows us to
773 // only account for the memory once.
774 using SharedMemoryMap
=
775 HashMap
<void*, SharedMemoryUse
, DefaultHasher
<void*>, SystemAllocPolicy
>;
779 extern JS_PUBLIC_API
const gc::SharedMemoryMap
& GetSharedMemoryUsageForZone(
783 * This function only reports GC heap memory,
784 * and not malloc allocated memory associated with GC things.
785 * It reports the total of all memory for the whole Runtime.
787 extern JS_PUBLIC_API
uint64_t GetGCHeapUsage(JSContext
* cx
);
789 class JS_PUBLIC_API CompartmentTransplantCallback
{
791 virtual JSObject
* getObjectToTransplant(JS::Compartment
* compartment
) = 0;
794 // Gather a set of remote window proxies by calling the callback on every
795 // compartment, then transform them into cross-compartment wrappers to newTarget
796 // via brain transplants. If there's a proxy in newTarget's compartment, it will
797 // get swapped with newTarget, and the value of newTarget will be updated. If
798 // the callback returns null for a compartment, no cross-compartment wrapper
799 // will be created for that compartment. Any non-null values it returns must be
800 // DOM remote proxies from the compartment that was passed in.
801 extern JS_PUBLIC_API
void RemapRemoteWindowProxies(
802 JSContext
* cx
, CompartmentTransplantCallback
* callback
,
803 JS::MutableHandleObject newTarget
);
805 extern JS_PUBLIC_API
JS::Zone
* GetObjectZoneFromAnyThread(const JSObject
* obj
);
809 #endif /* jsfriendapi_h */