зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1719795 part 5 - Change JSCLASS_PRIVATE_IS_NSISUPPORTS JSClasses to use a reserved slot instead. r=mccr8,jonco
This is a step towards removing object private slots. Classes with JSCLASS_PRIVATE_IS_NSISUPPORTS now use JSCLASS_SLOT0_IS_NSISUPPORTS instead. For most classes this means we need to add an extra reserved slot and remove the private slot. Global objects (SimpleGlobalObject and the XPConnect BackstagePass and Sandbox globals) however can use the JSCLASS_GLOBAL_APPLICATION_SLOTS already there. These slots were only used for WebIDL DOM globals until now. Differential Revision: https://phabricator.services.mozilla.com/D119502
This commit is contained in:
Родитель
5285ac89a9
Коммит
59f8590115
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
#include "js/Class.h"
|
||||
#include "js/Object.h" // JS::GetClass, JS::GetPrivate, JS::SetPrivate
|
||||
#include "js/Object.h" // JS::GetClass, JS::GetObjectISupports, JS::SetObjectISupports
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -76,9 +76,12 @@ static const JSClassOps SimpleGlobalClassOps = {
|
|||
static const js::ClassExtension SimpleGlobalClassExtension = {
|
||||
SimpleGlobal_moved};
|
||||
|
||||
static_assert(JSCLASS_GLOBAL_APPLICATION_SLOTS > 0,
|
||||
"Need at least one slot for JSCLASS_SLOT0_IS_NSISUPPORTS");
|
||||
|
||||
const JSClass SimpleGlobalClass = {"",
|
||||
JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS |
|
||||
JSCLASS_GLOBAL_FLAGS |
|
||||
JSCLASS_SLOT0_IS_NSISUPPORTS |
|
||||
JSCLASS_FOREGROUND_FINALIZE,
|
||||
&SimpleGlobalClassOps,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
|
@ -88,7 +91,7 @@ const JSClass SimpleGlobalClass = {"",
|
|||
static SimpleGlobalObject* GetSimpleGlobal(JSObject* global) {
|
||||
MOZ_ASSERT(JS::GetClass(global) == &SimpleGlobalClass);
|
||||
|
||||
return static_cast<SimpleGlobalObject*>(JS::GetPrivate(global));
|
||||
return JS::GetObjectISupports<SimpleGlobalObject>(global);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -139,7 +142,7 @@ JSObject* SimpleGlobalObject::Create(GlobalType globalType,
|
|||
new SimpleGlobalObject(global, globalType);
|
||||
|
||||
// Pass on ownership of globalObject to |global|.
|
||||
JS::SetPrivate(global, globalObject.forget().take());
|
||||
JS::SetObjectISupports(global, globalObject.forget().take());
|
||||
|
||||
if (proto.isObjectOrNull()) {
|
||||
JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull());
|
||||
|
|
|
@ -500,8 +500,8 @@ static const uint32_t JSCLASS_DELAY_METADATA_BUILDER = 1 << 1;
|
|||
// disposal mechanism.
|
||||
static const uint32_t JSCLASS_IS_WRAPPED_NATIVE = 1 << 2;
|
||||
|
||||
// Private is `nsISupports*`.
|
||||
static const uint32_t JSCLASS_PRIVATE_IS_NSISUPPORTS = 1 << 3;
|
||||
// First reserved slot is `PrivateValue(nsISupports*)` or `UndefinedValue`.
|
||||
static constexpr uint32_t JSCLASS_SLOT0_IS_NSISUPPORTS = 1 << 3;
|
||||
|
||||
// Objects are DOM.
|
||||
static const uint32_t JSCLASS_IS_DOMJSCLASS = 1 << 4;
|
||||
|
@ -706,6 +706,8 @@ struct alignas(js::gc::JSClassAlignBytes) JSClass {
|
|||
|
||||
bool isWrappedNative() const { return flags & JSCLASS_IS_WRAPPED_NATIVE; }
|
||||
|
||||
bool slot0IsISupports() const { return flags & JSCLASS_SLOT0_IS_NSISUPPORTS; }
|
||||
|
||||
static size_t offsetOfFlags() { return offsetof(JSClass, flags); }
|
||||
|
||||
// Internal / friend API accessors:
|
||||
|
|
|
@ -112,6 +112,31 @@ inline void SetReservedSlot(JSObject* obj, size_t slot, const Value& value) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get the pointer value (or nullptr if not set) from the
|
||||
* object's first reserved slot. Must only be used for objects with a JSClass
|
||||
* that has the JSCLASS_SLOT0_IS_NSISUPPORTS flag.
|
||||
*/
|
||||
template <typename T>
|
||||
inline T* GetObjectISupports(JSObject* obj) {
|
||||
MOZ_ASSERT(GetClass(obj)->slot0IsISupports());
|
||||
Value v = GetReservedSlot(obj, 0);
|
||||
return v.isUndefined() ? nullptr : static_cast<T*>(v.toPrivate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to store |PrivateValue(nsISupportsValue)| in the object's
|
||||
* first reserved slot. Must only be used for objects with a JSClass that has
|
||||
* the JSCLASS_SLOT0_IS_NSISUPPORTS flag.
|
||||
*
|
||||
* Note: the pointer is opaque to the JS engine (including the GC) so it's the
|
||||
* embedding's responsibility to trace or free this value.
|
||||
*/
|
||||
inline void SetObjectISupports(JSObject* obj, void* nsISupportsValue) {
|
||||
MOZ_ASSERT(GetClass(obj)->slot0IsISupports());
|
||||
SetReservedSlot(obj, 0, PrivateValue(nsISupportsValue));
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif // js_public_Object_h
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "builtin/streams/ReadableStreamReader.h" // js::CreateReadableStream{BYOB,Default}Reader, js::ForAuthorCodeBool
|
||||
#include "builtin/streams/WritableStream.h" // js::WritableStream
|
||||
#include "js/CallArgs.h" // JS::CallArgs{,FromVp}
|
||||
#include "js/Class.h" // JSCLASS_PRIVATE_IS_NSISUPPORTS, JSCLASS_HAS_PRIVATE, JS_NULL_CLASS_OPS
|
||||
#include "js/Class.h" // JSCLASS_SLOT0_IS_NSISUPPORTS, JSCLASS_HAS_PRIVATE, JS_NULL_CLASS_OPS
|
||||
#include "js/Conversions.h" // JS::ToBoolean
|
||||
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
|
||||
#include "js/PropertySpec.h" // JS{Function,Property}Spec, JS_FN, JS_PSG, JS_{FS,PS}_END
|
||||
|
@ -543,7 +543,7 @@ static bool FinishReadableStreamClassInit(JSContext* cx, Handle<JSObject*> ctor,
|
|||
// This function and everything below should be replaced with
|
||||
//
|
||||
// JS_STREAMS_CLASS_SPEC(ReadableStream, 0, SlotCount, 0,
|
||||
// JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE,
|
||||
// JSCLASS_SLOT0_IS_NSISUPPORTS,
|
||||
// JS_NULL_CLASS_OPS);
|
||||
//
|
||||
// when "pipeTo" is always enabled.
|
||||
|
@ -575,7 +575,7 @@ const JSClass ReadableStream::class_ = {
|
|||
"ReadableStream",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ReadableStream::SlotCount) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_ReadableStream) |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE,
|
||||
JSCLASS_SLOT0_IS_NSISUPPORTS,
|
||||
JS_NULL_CLASS_OPS, &ReadableStream::classSpec_};
|
||||
|
||||
const JSClass ReadableStream::protoClass_ = {
|
||||
|
|
|
@ -43,6 +43,12 @@ class ReadableStream : public NativeObject {
|
|||
* stream's constructor and thus cannot be in a different compartment.
|
||||
*/
|
||||
enum Slots {
|
||||
/**
|
||||
* Optional pointer to make the stream participate in Gecko's cycle
|
||||
* collection. See also JSCLASS_SLOT0_IS_NSISUPPORTS.
|
||||
*/
|
||||
Slot_ISupports,
|
||||
|
||||
Slot_Controller,
|
||||
Slot_Reader,
|
||||
Slot_State,
|
||||
|
|
|
@ -135,7 +135,9 @@ using JS::Value;
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
stream->setPrivate(nsISupportsObject_alreadyAddreffed);
|
||||
static_assert(Slot_ISupports == 0,
|
||||
"Must use right slot for JSCLASS_SLOT0_IS_NSISUPPORTS");
|
||||
JS::SetObjectISupports(stream, nsISupportsObject_alreadyAddreffed);
|
||||
|
||||
// Step 1: Set stream.[[state]] to "readable".
|
||||
stream->initStateBits(Readable);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "js/experimental/TypedData.h" // JS_GetArrayBufferViewData, JS_NewUint8Array
|
||||
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
|
||||
#include "js/GCAPI.h" // JS::AutoCheckCannotGC, JS::AutoSuppressGCAnalysis
|
||||
#include "js/Object.h" // JS::SetPrivate
|
||||
#include "js/Object.h" // JS::SetObjectISupports
|
||||
#include "js/RootingAPI.h" // JS::{,Mutable}Handle, JS::Rooted
|
||||
#include "js/Stream.h" // JS::ReadableStreamUnderlyingSource
|
||||
#include "js/Value.h" // JS::{,Object,Undefined}Value
|
||||
|
@ -399,7 +399,7 @@ JS_PUBLIC_API bool JS::ReadableStreamUpdateDataAvailableFromSource(
|
|||
|
||||
JS_PUBLIC_API void JS::ReadableStreamReleaseCCObject(JSObject* streamObj) {
|
||||
MOZ_ASSERT(JS::IsReadableStream(streamObj));
|
||||
JS::SetPrivate(streamObj, nullptr);
|
||||
JS::SetObjectISupports(streamObj, nullptr);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::ReadableStreamTee(JSContext* cx,
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "builtin/streams/WritableStreamDefaultWriter.h" // js::CreateWritableStreamDefaultWriter
|
||||
#include "builtin/streams/WritableStreamOperations.h" // js::WritableStream{Abort,Close{,QueuedOrInFlight}}
|
||||
#include "js/CallArgs.h" // JS::CallArgs{,FromVp}
|
||||
#include "js/Class.h" // JS{Function,Property}Spec, JS_{FS,PS}_END, JSCLASS_PRIVATE_IS_NSISUPPORTS, JSCLASS_HAS_PRIVATE, JS_NULL_CLASS_OPS
|
||||
#include "js/Class.h" // JS{Function,Property}Spec, JS_{FS,PS}_END, JSCLASS_SLOT0_IS_NSISUPPORTS, JSCLASS_HAS_PRIVATE, JS_NULL_CLASS_OPS
|
||||
#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
|
||||
#include "js/RealmOptions.h" // JS::RealmCreationOptions
|
||||
#include "js/RootingAPI.h" // JS::Handle, JS::Rooted
|
||||
|
@ -277,5 +277,4 @@ static const JSPropertySpec WritableStream_properties[] = {
|
|||
JS_PSG("locked", WritableStream_locked, 0), JS_PS_END};
|
||||
|
||||
JS_STREAMS_CLASS_SPEC(WritableStream, 0, SlotCount, 0,
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE,
|
||||
JS_NULL_CLASS_OPS);
|
||||
JSCLASS_SLOT0_IS_NSISUPPORTS, JS_NULL_CLASS_OPS);
|
||||
|
|
|
@ -33,6 +33,12 @@ class WritableStreamDefaultWriter;
|
|||
class WritableStream : public NativeObject {
|
||||
public:
|
||||
enum Slots {
|
||||
/**
|
||||
* Optional pointer to make the stream participate in Gecko's cycle
|
||||
* collection. See also JSCLASS_SLOT0_IS_NSISUPPORTS.
|
||||
*/
|
||||
Slot_ISupports,
|
||||
|
||||
/**
|
||||
* A WritableStream's associated controller is always created from under the
|
||||
* stream's constructor and thus cannot be in a different compartment.
|
||||
|
|
|
@ -76,7 +76,9 @@ using JS::Value;
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
stream->setPrivate(nsISupportsObject_alreadyAddreffed);
|
||||
static_assert(Slot_ISupports == 0,
|
||||
"Must use right slot for JSCLASS_SLOT0_IS_NSISUPPORTS");
|
||||
JS::SetObjectISupports(stream, nsISupportsObject_alreadyAddreffed);
|
||||
|
||||
stream->initWritableState();
|
||||
|
||||
|
|
|
@ -99,29 +99,29 @@ extern const js::ClassExtension XPC_WN_JSClassExtension;
|
|||
: XPCWrappedNative_Trace, \
|
||||
}
|
||||
|
||||
#define XPC_MAKE_CLASS(_name, _flags, _classOps) \
|
||||
{ \
|
||||
/* name */ \
|
||||
_name, \
|
||||
\
|
||||
/* flags */ \
|
||||
JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | \
|
||||
JSCLASS_IS_WRAPPED_NATIVE | JSCLASS_FOREGROUND_FINALIZE | \
|
||||
(((_flags)&XPC_SCRIPTABLE_IS_GLOBAL_OBJECT) \
|
||||
? XPCONNECT_GLOBAL_FLAGS \
|
||||
: 0), \
|
||||
\
|
||||
/* cOps */ \
|
||||
_classOps, \
|
||||
\
|
||||
/* spec */ \
|
||||
nullptr, \
|
||||
\
|
||||
/* ext */ \
|
||||
&XPC_WN_JSClassExtension, \
|
||||
\
|
||||
/* oOps */ \
|
||||
nullptr, \
|
||||
#define XPC_MAKE_CLASS(_name, _flags, _classOps) \
|
||||
{ \
|
||||
/* name */ \
|
||||
_name, \
|
||||
\
|
||||
/* flags */ \
|
||||
JSCLASS_SLOT0_IS_NSISUPPORTS | JSCLASS_IS_WRAPPED_NATIVE | \
|
||||
JSCLASS_FOREGROUND_FINALIZE | \
|
||||
(((_flags)&XPC_SCRIPTABLE_IS_GLOBAL_OBJECT) \
|
||||
? XPCONNECT_GLOBAL_FLAGS \
|
||||
: JSCLASS_HAS_RESERVED_SLOTS(1)), \
|
||||
\
|
||||
/* cOps */ \
|
||||
_classOps, \
|
||||
\
|
||||
/* spec */ \
|
||||
nullptr, \
|
||||
\
|
||||
/* ext */ \
|
||||
&XPC_WN_JSClassExtension, \
|
||||
\
|
||||
/* oOps */ \
|
||||
nullptr, \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,13 +36,14 @@ class SandboxPrivate : public nsIGlobalObject,
|
|||
// The type used to cast to void needs to match the one in GetPrivate.
|
||||
nsIScriptObjectPrincipal* sop =
|
||||
static_cast<nsIScriptObjectPrincipal*>(sbp.forget().take());
|
||||
JS::SetPrivate(global, sop);
|
||||
JS::SetObjectISupports(global, sop);
|
||||
}
|
||||
|
||||
static SandboxPrivate* GetPrivate(JSObject* obj) {
|
||||
// The type used to cast to void needs to match the one in Create.
|
||||
return static_cast<SandboxPrivate*>(
|
||||
static_cast<nsIScriptObjectPrincipal*>(JS::GetPrivate(obj)));
|
||||
nsIScriptObjectPrincipal* sop =
|
||||
JS::GetObjectISupports<nsIScriptObjectPrincipal>(obj);
|
||||
return static_cast<SandboxPrivate*>(sop);
|
||||
}
|
||||
|
||||
nsIPrincipal* GetPrincipal() override { return mPrincipal; }
|
||||
|
|
|
@ -55,9 +55,8 @@ using namespace JS;
|
|||
bool XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface) {
|
||||
const JSClass* jsclass = JS::GetClass(obj);
|
||||
MOZ_ASSERT(jsclass, "obj has no class");
|
||||
if (jsclass && (jsclass->flags & JSCLASS_HAS_PRIVATE) &&
|
||||
(jsclass->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
|
||||
*iface = (nsISupports*)xpc_GetJSPrivate(obj);
|
||||
if (jsclass && jsclass->slot0IsISupports()) {
|
||||
*iface = JS::GetObjectISupports<nsISupports>(obj);
|
||||
return true;
|
||||
}
|
||||
*iface = UnwrapDOMObjectToISupports(obj);
|
||||
|
|
|
@ -224,9 +224,7 @@ RealmPrivate::RealmPrivate(JS::Realm* realm) : scriptability(realm) {
|
|||
void RealmPrivate::Init(HandleObject aGlobal, const SiteIdentifier& aSite) {
|
||||
MOZ_ASSERT(aGlobal);
|
||||
DebugOnly<const JSClass*> clasp = JS::GetClass(aGlobal);
|
||||
MOZ_ASSERT(clasp->flags &
|
||||
(JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) ||
|
||||
dom::IsDOMClass(clasp));
|
||||
MOZ_ASSERT(clasp->slot0IsISupports() || dom::IsDOMClass(clasp));
|
||||
|
||||
Realm* realm = GetObjectRealmOrNull(aGlobal);
|
||||
|
||||
|
|
|
@ -227,8 +227,10 @@ nsresult XPCWrappedNative::WrapNewGlobal(JSContext* cx,
|
|||
// Set the JS object to the global we already created.
|
||||
wrapper->SetFlatJSObject(global);
|
||||
|
||||
// Set the private to the XPCWrappedNative.
|
||||
JS::SetPrivate(global, wrapper);
|
||||
// Set the reserved slot to the XPCWrappedNative.
|
||||
static_assert(JSCLASS_GLOBAL_APPLICATION_SLOTS > 0,
|
||||
"Need at least one slot for JSCLASS_SLOT0_IS_NSISUPPORTS");
|
||||
JS::SetObjectISupports(global, wrapper);
|
||||
|
||||
// There are dire comments elsewhere in the code about how a GC can
|
||||
// happen somewhere after wrapper initialization but before the wrapper is
|
||||
|
@ -651,7 +653,7 @@ bool XPCWrappedNative::Init(JSContext* cx, nsIXPCScriptable* aScriptable) {
|
|||
|
||||
SetFlatJSObject(object);
|
||||
|
||||
JS::SetPrivate(mFlatJSObject, this);
|
||||
JS::SetObjectISupports(mFlatJSObject, this);
|
||||
|
||||
return FinishInit(cx);
|
||||
}
|
||||
|
@ -809,7 +811,7 @@ void XPCWrappedNative::SystemIsBeingShutDown() {
|
|||
// We leak mIdentity (see above).
|
||||
|
||||
// Short circuit future finalization.
|
||||
JS::SetPrivate(mFlatJSObject, nullptr);
|
||||
JS::SetObjectISupports(mFlatJSObject, nullptr);
|
||||
UnsetFlatJSObject();
|
||||
|
||||
XPCWrappedNativeProto* proto = GetProto();
|
||||
|
|
|
@ -568,12 +568,11 @@ static void WrappedNativeFinalize(JSFreeOp* fop, JSObject* obj,
|
|||
if (clazz->flags & JSCLASS_DOM_GLOBAL) {
|
||||
mozilla::dom::DestroyProtoAndIfaceCache(obj);
|
||||
}
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
if (!p) {
|
||||
XPCWrappedNative* wrapper = JS::GetObjectISupports<XPCWrappedNative>(obj);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
|
||||
if (helperType == WN_HELPER) {
|
||||
wrapper->GetScriptable()->Finalize(wrapper, fop, obj);
|
||||
}
|
||||
|
@ -581,12 +580,11 @@ static void WrappedNativeFinalize(JSFreeOp* fop, JSObject* obj,
|
|||
}
|
||||
|
||||
static size_t WrappedNativeObjectMoved(JSObject* obj, JSObject* old) {
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
if (!p) {
|
||||
XPCWrappedNative* wrapper = JS::GetObjectISupports<XPCWrappedNative>(obj);
|
||||
if (!wrapper) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
|
||||
wrapper->FlatJSObjectMoved(obj, old);
|
||||
return 0;
|
||||
}
|
||||
|
@ -663,8 +661,8 @@ const js::ClassExtension XPC_WN_JSClassExtension = {
|
|||
|
||||
const JSClass XPC_WN_NoHelper_JSClass = {
|
||||
"XPCWrappedNative_NoHelper",
|
||||
JSCLASS_IS_WRAPPED_NATIVE | JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_FOREGROUND_FINALIZE,
|
||||
JSCLASS_IS_WRAPPED_NATIVE | JSCLASS_HAS_RESERVED_SLOTS(1) |
|
||||
JSCLASS_SLOT0_IS_NSISUPPORTS | JSCLASS_FOREGROUND_FINALIZE,
|
||||
&XPC_WN_NoHelper_JSClassOps,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
&XPC_WN_JSClassExtension,
|
||||
|
|
|
@ -1409,7 +1409,7 @@ class XPCWrappedNative final : public nsIXPConnectWrappedNative {
|
|||
|
||||
static XPCWrappedNative* Get(JSObject* obj) {
|
||||
MOZ_ASSERT(IS_WN_REFLECTOR(obj));
|
||||
return (XPCWrappedNative*)JS::GetPrivate(obj);
|
||||
return JS::GetObjectISupports<XPCWrappedNative>(obj);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -193,8 +193,11 @@ struct RuntimeStats;
|
|||
|
||||
} // namespace JS
|
||||
|
||||
#define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n) \
|
||||
JSCLASS_DOM_GLOBAL | JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | \
|
||||
static_assert(JSCLASS_GLOBAL_APPLICATION_SLOTS > 0,
|
||||
"Need at least one slot for JSCLASS_SLOT0_IS_NSISUPPORTS");
|
||||
|
||||
#define XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(n) \
|
||||
JSCLASS_DOM_GLOBAL | JSCLASS_SLOT0_IS_NSISUPPORTS | \
|
||||
JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS + n)
|
||||
|
||||
#define XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET \
|
||||
|
|
|
@ -777,15 +777,14 @@ JSObject* TransplantObjectNukingXrayWaiver(JSContext* cx,
|
|||
nsIGlobalObject* NativeGlobal(JSObject* obj) {
|
||||
obj = JS::GetNonCCWObjectGlobal(obj);
|
||||
|
||||
// Every global needs to hold a native as its private or be a
|
||||
// Every global needs to hold a native as its first reserved slot or be a
|
||||
// WebIDL object with an nsISupports DOM object.
|
||||
MOZ_ASSERT((JS::GetClass(obj)->flags &
|
||||
(JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE)) ||
|
||||
MOZ_ASSERT(JS::GetClass(obj)->slot0IsISupports() ||
|
||||
dom::UnwrapDOMObjectToISupports(obj));
|
||||
|
||||
nsISupports* native = dom::UnwrapDOMObjectToISupports(obj);
|
||||
if (!native) {
|
||||
native = static_cast<nsISupports*>(JS::GetPrivate(obj));
|
||||
native = JS::GetObjectISupports<nsISupports>(obj);
|
||||
MOZ_ASSERT(native);
|
||||
|
||||
// In some cases (like for windows) it is a wrapped native,
|
||||
|
|
|
@ -821,12 +821,11 @@ void CycleCollectedJSRuntime::NoteGCThingXPCOMChildren(
|
|||
return;
|
||||
}
|
||||
|
||||
// XXX This test does seem fragile, we should probably whitelist classes
|
||||
// XXX This test does seem fragile, we should probably allowlist classes
|
||||
// that do hold a strong reference, but that might not be possible.
|
||||
if (aClasp->flags & JSCLASS_HAS_PRIVATE &&
|
||||
aClasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "JS::GetPrivate(obj)");
|
||||
aCb.NoteXPCOMChild(static_cast<nsISupports*>(JS::GetPrivate(obj)));
|
||||
if (aClasp->slot0IsISupports()) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "JS::GetObjectISupports(obj)");
|
||||
aCb.NoteXPCOMChild(JS::GetObjectISupports<nsISupports>(obj));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче