Bug 1874684 - Part 24: Prevent arbitrary loops in NormalizedTimeDurationToDays. r...
[gecko.git] / js / src / jsfriendapi.h
blob6ad8140d910fb21180e40703d04ec39f883cbc43
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/. */
7 #ifndef jsfriendapi_h
8 #define jsfriendapi_h
10 #include "jspubtd.h"
12 #include "js/CallArgs.h"
13 #include "js/Class.h"
14 #include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin
15 #include "js/GCAPI.h"
16 #include "js/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"
22 class JSJitInfo;
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
32 * required.
34 extern JS_PUBLIC_API void JS_SetGrayGCRootsTracer(JSContext* cx,
35 JSGrayRootsTracer traceOp,
36 void* data);
38 extern JS_PUBLIC_API JSObject* JS_FindCompilationScope(JSContext* cx,
39 JS::HandleObject obj);
41 extern JS_PUBLIC_API JSFunction* JS_GetObjectFunction(JSObject* obj);
43 /**
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
47 * attached to them.
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);
63 /**
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);
71 /**
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);
81 namespace js {
83 /**
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);
95 } // namespace js
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
118 * NOT be copied.
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);
130 namespace js {
132 JS_PUBLIC_API bool IsArgumentsObject(JS::HandleObject obj);
134 JS_PUBLIC_API bool AddRawValueRoot(JSContext* cx, JS::Value* vp,
135 const char* name);
137 JS_PUBLIC_API void RemoveRawValueRoot(JSContext* cx, JS::Value* vp);
139 } // namespace js
141 namespace JS {
144 * Set all of the uninitialized lexicals on an object to undefined. Return
145 * true if any lexicals were initialized and false otherwise.
146 * */
147 extern JS_PUBLIC_API bool ForceLexicalInitialization(JSContext* cx,
148 HandleObject obj);
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);
166 } // namespace JS
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(
183 JSContext* cx,
184 JS::MutableHandle<mozilla::Maybe<JS::PropertyDescriptor>> desc);
186 struct JSFunctionSpecWithHelp {
187 const char* name;
188 JSNative call;
189 uint16_t nargs;
190 uint16_t flags;
191 const JSJitInfo* jitInfo;
192 const char* usage;
193 const char* help;
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, \
201 usage, help \
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);
209 namespace js {
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);
225 #ifdef DEBUG
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);
231 #endif
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);
250 * Instruct the runtime to restart draining the internal job queue after
251 * stopping it with StopDrainingJobQueue.
253 extern JS_PUBLIC_API void RestartDrainingJobQueue(JSContext* cx);
255 extern JS_PUBLIC_API void RunJobs(JSContext* cx);
257 extern JS_PUBLIC_API JS::Zone* GetRealmZone(JS::Realm* realm);
259 using PreserveWrapperCallback = bool (*)(JSContext*, JS::HandleObject);
260 using HasReleasedWrapperCallback = bool (*)(JS::HandleObject);
262 extern JS_PUBLIC_API bool IsSystemRealm(JS::Realm* realm);
264 extern JS_PUBLIC_API bool IsSystemCompartment(JS::Compartment* comp);
266 extern JS_PUBLIC_API bool IsSystemZone(JS::Zone* zone);
268 struct WeakMapTracer {
269 JSRuntime* runtime;
271 explicit WeakMapTracer(JSRuntime* rt) : runtime(rt) {}
273 // Weak map tracer callback, called once for every binding of every
274 // weak map that was live at the time of the last garbage collection.
276 // m will be nullptr if the weak map is not contained in a JS Object.
278 // The callback should not GC (and will assert in a debug build if it does
279 // so.)
280 virtual void trace(JSObject* m, JS::GCCellPtr key, JS::GCCellPtr value) = 0;
283 extern JS_PUBLIC_API void TraceWeakMaps(WeakMapTracer* trc);
285 extern JS_PUBLIC_API bool AreGCGrayBitsValid(JSRuntime* rt);
287 extern JS_PUBLIC_API bool ZoneGlobalsAreAllGray(JS::Zone* zone);
289 extern JS_PUBLIC_API bool IsCompartmentZoneSweepingOrCompacting(
290 JS::Compartment* comp);
292 using IterateGCThingCallback = void (*)(void*, JS::GCCellPtr,
293 const JS::AutoRequireNoGC&);
295 extern JS_PUBLIC_API void TraceGrayWrapperTargets(JSTracer* trc,
296 JS::Zone* zone);
299 * Invoke cellCallback on every gray JSObject in the given zone.
301 extern JS_PUBLIC_API void IterateGrayObjects(
302 JS::Zone* zone, IterateGCThingCallback cellCallback, void* data);
304 #if defined(JS_GC_ZEAL) || defined(DEBUG)
305 // Trace the heap and check there are no black to gray edges. These are
306 // not allowed since the cycle collector could throw away the gray thing and
307 // leave a dangling pointer.
309 // This doesn't trace weak maps as these are handled separately.
310 extern JS_PUBLIC_API bool CheckGrayMarkingState(JSRuntime* rt);
311 #endif
313 // Note: this returns nullptr iff |zone| is the atoms zone.
314 extern JS_PUBLIC_API JS::Realm* GetAnyRealmInZone(JS::Zone* zone);
316 // Returns the first realm's global in a compartment. Note: this is not
317 // guaranteed to always be the same realm because individual realms can be
318 // collected by the GC.
319 extern JS_PUBLIC_API JSObject* GetFirstGlobalInCompartment(
320 JS::Compartment* comp);
322 // Returns true if the compartment contains a global object and this global is
323 // not being collected.
324 extern JS_PUBLIC_API bool CompartmentHasLiveGlobal(JS::Compartment* comp);
326 // Returns true if this compartment can be shared across multiple Realms. Used
327 // when we're looking for an existing compartment to place a new Realm in.
328 extern JS_PUBLIC_API bool IsSharableCompartment(JS::Compartment* comp);
330 // This is equal to |&JSObject::class_|. Use it in places where you don't want
331 // to #include vm/JSObject.h.
332 extern JS_PUBLIC_DATA const JSClass* const ObjectClassPtr;
334 JS_PUBLIC_API const JSClass* ProtoKeyToClass(JSProtoKey key);
336 // Returns the key for the class inherited by a given standard class (that
337 // is to say, the prototype of this standard class's prototype).
339 // You must be sure that this corresponds to a standard class with a cached
340 // JSProtoKey before calling this function. In general |key| will match the
341 // cached proto key, except in cases where multiple JSProtoKeys share a
342 // JSClass.
343 inline JSProtoKey InheritanceProtoKeyForStandardClass(JSProtoKey key) {
344 // [Object] has nothing to inherit from.
345 if (key == JSProto_Object) {
346 return JSProto_Null;
349 // If we're ClassSpec defined return the proto key from that
350 if (ProtoKeyToClass(key)->specDefined()) {
351 return ProtoKeyToClass(key)->specInheritanceProtoKey();
354 // Otherwise, we inherit [Object].
355 return JSProto_Object;
358 JS_PUBLIC_API bool ShouldIgnorePropertyDefinition(JSContext* cx, JSProtoKey key,
359 jsid id);
361 JS_PUBLIC_API bool IsFunctionObject(JSObject* obj);
363 JS_PUBLIC_API bool UninlinedIsCrossCompartmentWrapper(const JSObject* obj);
365 // CrossCompartmentWrappers are shared by all realms within the compartment, so
366 // getting a wrapper's realm usually doesn't make sense.
367 static MOZ_ALWAYS_INLINE JS::Realm* GetNonCCWObjectRealm(JSObject* obj) {
368 MOZ_ASSERT(!js::UninlinedIsCrossCompartmentWrapper(obj));
369 return reinterpret_cast<JS::shadow::Object*>(obj)->shape->base->realm;
372 JS_PUBLIC_API void AssertSameCompartment(JSContext* cx, JSObject* obj);
374 JS_PUBLIC_API void AssertSameCompartment(JSContext* cx, JS::HandleValue v);
376 #ifdef JS_DEBUG
377 JS_PUBLIC_API void AssertSameCompartment(JSObject* objA, JSObject* objB);
378 #else
379 inline void AssertSameCompartment(JSObject* objA, JSObject* objB) {}
380 #endif
382 JS_PUBLIC_API void NotifyAnimationActivity(JSObject* obj);
384 JS_PUBLIC_API JSFunction* DefineFunctionWithReserved(
385 JSContext* cx, JSObject* obj, const char* name, JSNative call,
386 unsigned nargs, unsigned attrs);
388 JS_PUBLIC_API JSFunction* NewFunctionWithReserved(JSContext* cx, JSNative call,
389 unsigned nargs,
390 unsigned flags,
391 const char* name);
393 JS_PUBLIC_API JSFunction* NewFunctionByIdWithReserved(JSContext* cx,
394 JSNative native,
395 unsigned nargs,
396 unsigned flags, jsid id);
398 JS_PUBLIC_API JSFunction* NewFunctionByIdWithReservedAndProto(
399 JSContext* cx, JSNative native, JS::Handle<JSObject*> proto, unsigned nargs,
400 unsigned flags, jsid id);
403 * Get or set function's reserved slot value.
404 * `fun` should be a function created with `*WithReserved` API above.
405 * Such functions have 2 reserved slots, and `which` can be either 0 or 1.
407 JS_PUBLIC_API const JS::Value& GetFunctionNativeReserved(JSObject* fun,
408 size_t which);
410 JS_PUBLIC_API void SetFunctionNativeReserved(JSObject* fun, size_t which,
411 const JS::Value& val);
413 JS_PUBLIC_API bool FunctionHasNativeReserved(JSObject* fun);
415 JS_PUBLIC_API bool GetObjectProto(JSContext* cx, JS::HandleObject obj,
416 JS::MutableHandleObject proto);
418 extern JS_PUBLIC_API JSObject* GetStaticPrototype(JSObject* obj);
420 JS_PUBLIC_API bool GetRealmOriginalEval(JSContext* cx,
421 JS::MutableHandleObject eval);
424 * Add some or all property keys of obj to the id vector *props.
426 * The flags parameter controls which property keys are added. Pass a
427 * combination of the following bits:
429 * JSITER_OWNONLY - Don't also search the prototype chain; only consider
430 * obj's own properties.
432 * JSITER_HIDDEN - Include nonenumerable properties.
434 * JSITER_SYMBOLS - Include property keys that are symbols. The default
435 * behavior is to filter out symbols.
437 * JSITER_SYMBOLSONLY - Exclude non-symbol property keys.
439 * This is the closest C++ API we have to `Reflect.ownKeys(obj)`, or
440 * equivalently, the ES6 [[OwnPropertyKeys]] internal method. Pass
441 * `JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS` as flags to get
442 * results that match the output of Reflect.ownKeys.
444 JS_PUBLIC_API bool GetPropertyKeys(JSContext* cx, JS::HandleObject obj,
445 unsigned flags,
446 JS::MutableHandleIdVector props);
448 JS_PUBLIC_API bool AppendUnique(JSContext* cx, JS::MutableHandleIdVector base,
449 JS::HandleIdVector others);
452 * Determine whether the given string is an array index in the sense of
453 * <https://tc39.github.io/ecma262/#array-index>.
455 * If it isn't, returns false.
457 * If it is, returns true and outputs the index in *indexp.
459 JS_PUBLIC_API bool StringIsArrayIndex(JSLinearString* str, uint32_t* indexp);
462 * Overload of StringIsArrayIndex taking a (char16_t*,length) pair. Behaves
463 * the same as the JSLinearString version.
465 JS_PUBLIC_API bool StringIsArrayIndex(const char16_t* str, uint32_t length,
466 uint32_t* indexp);
468 JS_PUBLIC_API void SetPreserveWrapperCallbacks(
469 JSContext* cx, PreserveWrapperCallback preserveWrapper,
470 HasReleasedWrapperCallback hasReleasedWrapper);
472 JS_PUBLIC_API bool IsObjectInContextCompartment(JSObject* obj,
473 const JSContext* cx);
476 * NB: keep these in sync with the copy in builtin/SelfHostingDefines.h.
478 /* 0x1 is no longer used */
479 /* 0x2 is no longer used */
480 #define JSITER_PRIVATE 0x4 /* Include private names in iteration */
481 #define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
482 #define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
483 #define JSITER_SYMBOLS 0x20 /* also include symbol property keys */
484 #define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
485 #define JSITER_FORAWAITOF 0x80 /* for-await-of */
487 using DOMInstanceClassHasProtoAtDepth = bool (*)(const JSClass*, uint32_t,
488 uint32_t);
489 struct JSDOMCallbacks {
490 DOMInstanceClassHasProtoAtDepth instanceClassMatchesProto;
492 using DOMCallbacks = struct JSDOMCallbacks;
494 extern JS_PUBLIC_API void SetDOMCallbacks(JSContext* cx,
495 const DOMCallbacks* callbacks);
497 extern JS_PUBLIC_API const DOMCallbacks* GetDOMCallbacks(JSContext* cx);
499 extern JS_PUBLIC_API JSObject* GetTestingFunctions(JSContext* cx);
501 /* Implemented in jsexn.cpp. */
504 * Get an error type name from a JSExnType constant.
505 * Returns nullptr for invalid arguments and JSEXN_INTERNALERR
507 extern JS_PUBLIC_API JSLinearString* GetErrorTypeName(JSContext* cx,
508 int16_t exnType);
510 /* Implemented in CrossCompartmentWrapper.cpp. */
511 typedef enum NukeReferencesToWindow {
512 NukeWindowReferences,
513 DontNukeWindowReferences
514 } NukeReferencesToWindow;
516 typedef enum NukeReferencesFromTarget {
517 NukeAllReferences,
518 NukeIncomingReferences,
519 } NukeReferencesFromTarget;
522 * These filters are designed to be ephemeral stack classes, and thus don't
523 * do any rooting or holding of their members.
525 struct CompartmentFilter {
526 virtual bool match(JS::Compartment* c) const = 0;
529 struct AllCompartments : public CompartmentFilter {
530 virtual bool match(JS::Compartment* c) const override { return true; }
533 struct SingleCompartment : public CompartmentFilter {
534 JS::Compartment* ours;
535 explicit SingleCompartment(JS::Compartment* c) : ours(c) {}
536 virtual bool match(JS::Compartment* c) const override { return c == ours; }
539 extern JS_PUBLIC_API bool NukeCrossCompartmentWrappers(
540 JSContext* cx, const CompartmentFilter& sourceFilter, JS::Realm* target,
541 NukeReferencesToWindow nukeReferencesToWindow,
542 NukeReferencesFromTarget nukeReferencesFromTarget);
544 extern JS_PUBLIC_API bool AllowNewWrapper(JS::Compartment* target,
545 JSObject* obj);
547 extern JS_PUBLIC_API bool NukedObjectRealm(JSObject* obj);
549 /* Implemented in jsdate.cpp. */
551 /** Detect whether the internal date value is NaN. */
552 extern JS_PUBLIC_API bool DateIsValid(JSContext* cx, JS::HandleObject obj,
553 bool* isValid);
555 extern JS_PUBLIC_API bool DateGetMsecSinceEpoch(JSContext* cx,
556 JS::HandleObject obj,
557 double* msecSinceEpoch);
559 } /* namespace js */
561 namespace js {
563 /* Implemented in vm/StructuredClone.cpp. */
564 extern JS_PUBLIC_API uint64_t GetSCOffset(JSStructuredCloneWriter* writer);
566 } // namespace js
568 namespace js {
570 /* Statically asserted in FunctionFlags.cpp. */
571 static const unsigned JS_FUNCTION_INTERPRETED_BITS = 0x0060;
573 } // namespace js
575 static MOZ_ALWAYS_INLINE const JSJitInfo* FUNCTION_VALUE_TO_JITINFO(
576 const JS::Value& v) {
577 JSObject* obj = &v.toObject();
578 MOZ_ASSERT(JS::GetClass(obj)->isJSFunction());
580 auto* fun = reinterpret_cast<JS::shadow::Function*>(obj);
581 MOZ_ASSERT(!(fun->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS),
582 "Unexpected non-native function");
584 return static_cast<const JSJitInfo*>(fun->jitInfoOrScript());
587 static MOZ_ALWAYS_INLINE void SET_JITINFO(JSFunction* func,
588 const JSJitInfo* info) {
589 auto* fun = reinterpret_cast<JS::shadow::Function*>(func);
590 MOZ_ASSERT(!(fun->flagsAndArgCount() & js::JS_FUNCTION_INTERPRETED_BITS));
592 fun->setJitInfoOrScript(const_cast<JSJitInfo*>(info));
595 static_assert(sizeof(jsid) == sizeof(void*));
597 namespace js {
599 static MOZ_ALWAYS_INLINE JS::Value IdToValue(jsid id) {
600 if (id.isString()) {
601 return JS::StringValue(id.toString());
603 if (id.isInt()) {
604 return JS::Int32Value(id.toInt());
606 if (id.isSymbol()) {
607 return JS::SymbolValue(id.toSymbol());
609 MOZ_ASSERT(id.isVoid());
610 return JS::UndefinedValue();
614 * PrepareScriptEnvironmentAndInvoke asserts the embedder has registered a
615 * ScriptEnvironmentPreparer and then it calls the preparer's 'invoke' method
616 * with the given |closure|, with the assumption that the preparer will set up
617 * any state necessary to run script in |global|, invoke |closure| with a valid
618 * JSContext*, report any exceptions thrown from the closure, and return.
620 * PrepareScriptEnvironmentAndInvoke will report any exceptions that are thrown
621 * by the closure. Consumers who want to propagate back whether the closure
622 * succeeded should do so via members of the closure itself.
625 struct ScriptEnvironmentPreparer {
626 struct Closure {
627 virtual bool operator()(JSContext* cx) = 0;
630 virtual void invoke(JS::HandleObject global, Closure& closure) = 0;
633 extern JS_PUBLIC_API void PrepareScriptEnvironmentAndInvoke(
634 JSContext* cx, JS::HandleObject global,
635 ScriptEnvironmentPreparer::Closure& closure);
637 JS_PUBLIC_API void SetScriptEnvironmentPreparer(
638 JSContext* cx, ScriptEnvironmentPreparer* preparer);
640 // Abstract base class for objects that build allocation metadata for JavaScript
641 // values.
642 struct AllocationMetadataBuilder {
643 AllocationMetadataBuilder() = default;
645 // Return a metadata object for the newly constructed object |obj|, or
646 // nullptr if there's no metadata to attach.
648 // Implementations should treat all errors as fatal; there is no way to
649 // report errors from this callback. In particular, the caller provides an
650 // oomUnsafe for overriding implementations to use.
651 virtual JSObject* build(JSContext* cx, JS::HandleObject obj,
652 AutoEnterOOMUnsafeRegion& oomUnsafe) const {
653 return nullptr;
658 * Specify a callback to invoke when creating each JS object in the current
659 * compartment, which may return a metadata object to associate with the
660 * object.
662 JS_PUBLIC_API void SetAllocationMetadataBuilder(
663 JSContext* cx, const AllocationMetadataBuilder* callback);
665 /** Get the metadata associated with an object. */
666 JS_PUBLIC_API JSObject* GetAllocationMetadata(JSObject* obj);
668 JS_PUBLIC_API bool GetElementsWithAdder(JSContext* cx, JS::HandleObject obj,
669 JS::HandleObject receiver,
670 uint32_t begin, uint32_t end,
671 js::ElementAdder* adder);
673 JS_PUBLIC_API bool ForwardToNative(JSContext* cx, JSNative native,
674 const JS::CallArgs& args);
677 * Helper function for HTMLDocument and HTMLFormElement.
679 * These are the only two interfaces that have [OverrideBuiltins], a named
680 * getter, and no named setter. They're implemented as proxies with a custom
681 * getOwnPropertyDescriptor() method. Unfortunately, overriding
682 * getOwnPropertyDescriptor() automatically affects the behavior of set(),
683 * which normally is just common sense but is *not* desired for these two
684 * interfaces.
686 * The fix is for these two interfaces to override set() to ignore the
687 * getOwnPropertyDescriptor() override.
689 * SetPropertyIgnoringNamedGetter is exposed to make it easier to override
690 * set() in this way. It carries out all the steps of BaseProxyHandler::set()
691 * except the initial getOwnPropertyDescriptor() call. The caller must supply
692 * that descriptor as the 'ownDesc' parameter.
694 * Implemented in proxy/BaseProxyHandler.cpp.
696 JS_PUBLIC_API bool SetPropertyIgnoringNamedGetter(
697 JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
698 JS::HandleValue receiver,
699 JS::Handle<mozilla::Maybe<JS::PropertyDescriptor>> ownDesc,
700 JS::ObjectOpResult& result);
702 // This function is for one specific use case, please don't use this for
703 // anything else!
704 extern JS_PUBLIC_API bool ExecuteInFrameScriptEnvironment(
705 JSContext* cx, JS::HandleObject obj, JS::HandleScript script,
706 JS::MutableHandleObject scope);
708 extern JS_PUBLIC_API bool IsSavedFrame(JSObject* obj);
710 // Matches the condition in js/src/jit/ProcessExecutableMemory.cpp
711 #if defined(XP_WIN)
712 // Parameters use void* types to avoid #including windows.h. The return value of
713 // this function is returned from the exception handler.
714 typedef long (*JitExceptionHandler)(void* exceptionRecord, // PEXECTION_RECORD
715 void* context); // PCONTEXT
718 * Windows uses "structured exception handling" to handle faults. When a fault
719 * occurs, the stack is searched for a handler (similar to C++ exception
720 * handling). If the search does not find a handler, the "unhandled exception
721 * filter" is called. Breakpad uses the unhandled exception filter to do crash
722 * reporting. Unfortunately, on Win64, JIT code on the stack completely throws
723 * off this unwinding process and prevents the unhandled exception filter from
724 * being called. The reason is that Win64 requires unwind information be
725 * registered for all code regions and JIT code has none. While it is possible
726 * to register full unwind information for JIT code, this is a lot of work (one
727 * has to be able to recover the frame pointer at any PC) so instead we register
728 * a handler for all JIT code that simply calls breakpad's unhandled exception
729 * filter (which will perform crash reporting and then terminate the process).
730 * This would be wrong if there was an outer __try block that expected to handle
731 * the fault, but this is not generally allowed.
733 * Gecko must call SetJitExceptionFilter before any JIT code is compiled and
734 * only once per process.
736 extern JS_PUBLIC_API void SetJitExceptionHandler(JitExceptionHandler handler);
737 #endif
739 extern JS_PUBLIC_API bool ReportIsNotFunction(JSContext* cx, JS::HandleValue v);
741 class MOZ_STACK_CLASS JS_PUBLIC_API AutoAssertNoContentJS {
742 public:
743 explicit AutoAssertNoContentJS(JSContext* cx);
744 ~AutoAssertNoContentJS();
746 private:
747 JSContext* context_;
748 bool prevAllowContentJS_;
752 * This function reports memory used by a zone in bytes, this includes:
753 * * The size of this JS GC zone.
754 * * Malloc memory referred to from this zone.
755 * * JIT memory for this zone.
757 * Note that malloc memory referred to from this zone can include
758 * SharedArrayBuffers which may also be referred to from other zones. Adding the
759 * memory usage of multiple zones may lead to an over-estimate.
761 extern JS_PUBLIC_API uint64_t GetMemoryUsageForZone(JS::Zone* zone);
763 enum class MemoryUse : uint8_t;
765 namespace gc {
767 struct SharedMemoryUse {
768 explicit SharedMemoryUse(MemoryUse use) : count(0), nbytes(0) {
769 #ifdef DEBUG
770 this->use = use;
771 #endif
774 size_t count;
775 size_t nbytes;
776 #ifdef DEBUG
777 MemoryUse use;
778 #endif
781 // A map which tracks shared memory uses (shared in the sense that an allocation
782 // can be referenced by more than one GC thing in a zone). This allows us to
783 // only account for the memory once.
784 using SharedMemoryMap =
785 HashMap<void*, SharedMemoryUse, DefaultHasher<void*>, SystemAllocPolicy>;
787 } /* namespace gc */
789 extern JS_PUBLIC_API const gc::SharedMemoryMap& GetSharedMemoryUsageForZone(
790 JS::Zone* zone);
793 * This function only reports GC heap memory,
794 * and not malloc allocated memory associated with GC things.
795 * It reports the total of all memory for the whole Runtime.
797 extern JS_PUBLIC_API uint64_t GetGCHeapUsage(JSContext* cx);
799 class JS_PUBLIC_API CompartmentTransplantCallback {
800 public:
801 virtual JSObject* getObjectToTransplant(JS::Compartment* compartment) = 0;
804 // Gather a set of remote window proxies by calling the callback on every
805 // compartment, then transform them into cross-compartment wrappers to newTarget
806 // via brain transplants. If there's a proxy in newTarget's compartment, it will
807 // get swapped with newTarget, and the value of newTarget will be updated. If
808 // the callback returns null for a compartment, no cross-compartment wrapper
809 // will be created for that compartment. Any non-null values it returns must be
810 // DOM remote proxies from the compartment that was passed in.
811 extern JS_PUBLIC_API void RemapRemoteWindowProxies(
812 JSContext* cx, CompartmentTransplantCallback* callback,
813 JS::MutableHandleObject newTarget);
815 extern JS_PUBLIC_API JS::Zone* GetObjectZoneFromAnyThread(const JSObject* obj);
817 } /* namespace js */
819 #endif /* jsfriendapi_h */