diff options
Diffstat (limited to 'js/public/GlobalObject.h')
-rw-r--r-- | js/public/GlobalObject.h | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/js/public/GlobalObject.h b/js/public/GlobalObject.h new file mode 100644 index 0000000000..22da1fc28b --- /dev/null +++ b/js/public/GlobalObject.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef js_GlobalObject_h +#define js_GlobalObject_h + +#include "mozilla/Attributes.h" + +#include "jstypes.h" + +#include "js/TypeDecls.h" + +class JS_PUBLIC_API JSTracer; + +struct JSClassOps; + +extern JS_PUBLIC_API bool JS_IsGlobalObject(JSObject* obj); + +namespace JS { + +class JS_PUBLIC_API RealmOptions; + +/** + * Get the current realm's global. Returns nullptr if no realm has been + * entered. + */ +extern JS_PUBLIC_API JSObject* CurrentGlobalOrNull(JSContext* cx); + +/** + * Get the global object associated with an object's realm. The object must not + * be a cross-compartment wrapper (because CCWs are shared by all realms in the + * compartment). + */ +extern JS_PUBLIC_API JSObject* GetNonCCWObjectGlobal(JSObject* obj); + +/** + * During global creation, we fire notifications to callbacks registered + * via the Debugger API. These callbacks are arbitrary script, and can touch + * the global in arbitrary ways. When that happens, the global should not be + * in a half-baked state. But this creates a problem for consumers that need + * to set slots on the global to put it in a consistent state. + * + * This API provides a way for consumers to set slots atomically (immediately + * after the global is created), before any debugger hooks are fired. It's + * unfortunately on the clunky side, but that's the way the cookie crumbles. + * + * If callers have no additional state on the global to set up, they may pass + * |FireOnNewGlobalHook| to JS_NewGlobalObject, which causes that function to + * fire the hook as its final act before returning. Otherwise, callers should + * pass |DontFireOnNewGlobalHook|, which means that they are responsible for + * invoking JS_FireOnNewGlobalObject upon successfully creating the global. If + * an error occurs and the operation aborts, callers should skip firing the + * hook. But otherwise, callers must take care to fire the hook exactly once + * before compiling any script in the global's scope (we have assertions in + * place to enforce this). This lets us be sure that debugger clients never miss + * breakpoints. + */ +enum OnNewGlobalHookOption { FireOnNewGlobalHook, DontFireOnNewGlobalHook }; + +} // namespace JS + +extern JS_PUBLIC_API JSObject* JS_NewGlobalObject( + JSContext* cx, const JSClass* clasp, JSPrincipals* principals, + JS::OnNewGlobalHookOption hookOption, const JS::RealmOptions& options); +/** + * Spidermonkey does not have a good way of keeping track of what compartments + * should be marked on their own. We can mark the roots unconditionally, but + * marking GC things only relevant in live compartments is hard. To mitigate + * this, we create a static trace hook, installed on each global object, from + * which we can be sure the compartment is relevant, and mark it. + * + * It is still possible to specify custom trace hooks for global object classes. + * They can be provided via the RealmOptions passed to JS_NewGlobalObject. + */ +extern JS_PUBLIC_API void JS_GlobalObjectTraceHook(JSTracer* trc, + JSObject* global); + +namespace JS { + +/** + * This allows easily constructing a global object without having to deal with + * JSClassOps, forgetting to add JS_GlobalObjectTraceHook, or forgetting to call + * JS::InitRealmStandardClasses(). Example: + * + * const JSClass globalClass = { "MyGlobal", JSCLASS_GLOBAL_FLAGS, + * &JS::DefaultGlobalClassOps }; + * JS_NewGlobalObject(cx, &globalClass, ...); + */ +extern JS_PUBLIC_DATA const JSClassOps DefaultGlobalClassOps; + +} // namespace JS + +extern JS_PUBLIC_API void JS_FireOnNewGlobalObject(JSContext* cx, + JS::HandleObject global); + +#endif // js_GlobalObject_h |