Bug 1363200 - JSAPI for realms: JS::SetDestroyRealmCallback. r=sfink

--HG--
extra : rebase_source : ad62e332bab6c31db2c98581163b1ca5fe8103f0
extra : intermediate-source : 0f72e0175f55a309ea4bc70240347e6659174af4
extra : source : ac9c7e04c174c8b2e4ca0e533a8a2838d293f700
This commit is contained in:
Jason Orendorff 2017-05-23 16:35:31 -05:00
parent cb4a93f642
commit 4e0c34d1c3
9 changed files with 42 additions and 15 deletions

View File

@ -69,6 +69,26 @@ GetRealmPrivate(Realm* realm);
extern JS_PUBLIC_API(void)
SetRealmPrivate(Realm* realm, void* data);
typedef void
(* DestroyRealmCallback)(JSFreeOp* fop, Realm* realm);
// Set the callback SpiderMonkey calls just before garbage-collecting a realm.
// Embeddings can use this callback to free private data associated with the
// realm via SetRealmPrivate.
//
// By the time this is called, the global object for the realm has already been
// collected.
extern JS_PUBLIC_API(void)
SetDestroyRealmCallback(JSContext* cx, DestroyRealmCallback callback);
typedef void
(* RealmNameCallback)(JSContext* cx, Handle<Realm*> realm, char* buf, size_t bufsize);
// Set the callback SpiderMonkey calls to get the name of a realm, for
// diagnostic output.
extern JS_PUBLIC_API(void)
SetRealmNameCallback(JSContext* cx, RealmNameCallback callback);
extern JS_PUBLIC_API(JSObject*)
GetRealmObjectPrototype(JSContext* cx);

View File

@ -28,6 +28,7 @@ class JSObject;
class JSScript;
class JSString;
class JSAddonId;
struct JSFreeOp;
struct jsid;

View File

@ -683,12 +683,6 @@ JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback)
cx->runtime()->compartmentNameCallback = callback;
}
JS_PUBLIC_API(void)
JS_SetRealmNameCallback(JSContext* cx, JSRealmNameCallback callback)
{
cx->runtime()->realmNameCallback = callback;
}
JS_PUBLIC_API(void)
JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks)
{

View File

@ -716,9 +716,6 @@ typedef void
(* JSCompartmentNameCallback)(JSContext* cx, JSCompartment* compartment,
char* buf, size_t bufsize);
typedef void
(* JSRealmNameCallback)(JSContext* cx, JS::Handle<JS::Realm*> realm, char* buf, size_t bufsize);
/**
* Callback used by memory reporting to ask the embedder how much memory an
* external string is keeping alive. The embedder is expected to return a value
@ -1371,9 +1368,6 @@ JS_SetSizeOfIncludingThisCompartmentCallback(JSContext* cx,
extern JS_PUBLIC_API(void)
JS_SetCompartmentNameCallback(JSContext* cx, JSCompartmentNameCallback callback);
extern JS_PUBLIC_API(void)
JS_SetRealmNameCallback(JSContext* cx, JSRealmNameCallback callback);
extern JS_PUBLIC_API(void)
JS_SetWrapObjectCallbacks(JSContext* cx, const JSWrapObjectCallbacks* callbacks);

View File

@ -3444,6 +3444,8 @@ void
JSCompartment::destroy(FreeOp* fop)
{
JSRuntime* rt = fop->runtime();
if (auto callback = rt->destroyRealmCallback)
callback(fop, JS::GetRealmForCompartment(this));
if (auto callback = rt->destroyCompartmentCallback)
callback(fop, this);
if (principals())

View File

@ -46,6 +46,18 @@ JS::SetRealmPrivate(JS::Realm* realm, void* data)
GetCompartmentForRealm(realm)->realmData = data;
}
JS_PUBLIC_API(void)
JS::SetDestroyRealmCallback(JSContext* cx, JS::DestroyRealmCallback callback)
{
cx->runtime()->destroyRealmCallback = callback;
}
JS_PUBLIC_API(void)
JS::SetRealmNameCallback(JSContext* cx, JS::RealmNameCallback callback)
{
cx->runtime()->realmNameCallback = callback;
}
JS_PUBLIC_API(JSObject*)
JS::GetRealmObjectPrototype(JSContext* cx)
{

View File

@ -119,6 +119,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
destroyCompartmentCallback(nullptr),
sizeOfIncludingThisCompartmentCallback(nullptr),
compartmentNameCallback(nullptr),
destroyRealmCallback(nullptr),
realmNameCallback(nullptr),
externalStringSizeofCallback(nullptr),
securityCallbacks(&NullSecurityCallbacks),

View File

@ -501,8 +501,11 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
/* Call this to get the name of a compartment. */
js::ActiveThreadData<JSCompartmentNameCallback> compartmentNameCallback;
/* Realm destroy callback. */
js::ActiveThreadData<JS::DestroyRealmCallback> destroyRealmCallback;
/* Call this to get the name of a realm. */
js::ActiveThreadData<JSRealmNameCallback> realmNameCallback;
js::ActiveThreadData<JS::RealmNameCallback> realmNameCallback;
/* Callback for doing memory reporting on external strings. */
js::ActiveThreadData<JSExternalStringSizeofCallback> externalStringSizeofCallback;

View File

@ -2664,7 +2664,7 @@ CompartmentNameCallback(JSContext* cx, JSCompartment* comp,
}
static void
RealmNameCallback(JSContext* cx, JS::Handle<JS::Realm*> realm, char* buf, size_t bufsize)
GetRealmName(JSContext* cx, JS::Handle<JS::Realm*> realm, char* buf, size_t bufsize)
{
JSCompartment* comp = JS::GetCompartmentForRealm(realm);
CompartmentNameCallback(cx, comp, buf, bufsize);
@ -2841,7 +2841,7 @@ XPCJSRuntime::Initialize(JSContext* cx)
JS_SetDestroyCompartmentCallback(cx, CompartmentDestroyedCallback);
JS_SetSizeOfIncludingThisCompartmentCallback(cx, CompartmentSizeOfIncludingThisCallback);
JS_SetCompartmentNameCallback(cx, CompartmentNameCallback);
JS_SetRealmNameCallback(cx, RealmNameCallback);
JS::SetRealmNameCallback(cx, GetRealmName);
mPrevGCSliceCallback = JS::SetGCSliceCallback(cx, GCSliceCallback);
mPrevDoCycleCollectionCallback = JS::SetDoCycleCollectionCallback(cx,
DoCycleCollectionCallback);