mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 650161 - Use the object moved hook to update the wrapper cache r=terrence r=bz r=bholley
This commit is contained in:
parent
51efcd8004
commit
c60aa1033f
@ -668,10 +668,12 @@ public:
|
||||
unsigned flags,
|
||||
JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
|
||||
|
||||
static void ObjectMoved(JSObject *obj, const JSObject *old);
|
||||
|
||||
static const nsOuterWindowProxy singleton;
|
||||
|
||||
protected:
|
||||
nsGlobalWindow* GetWindow(JSObject *proxy) const
|
||||
static nsGlobalWindow* GetWindow(JSObject *proxy)
|
||||
{
|
||||
return nsGlobalWindow::FromSupports(
|
||||
static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate()));
|
||||
@ -703,7 +705,8 @@ const js::Class OuterWindowProxyClass =
|
||||
nullptr, /* outerObject */
|
||||
js::proxy_innerObject,
|
||||
nullptr, /* iteratorObject */
|
||||
false /* isWrappedNative */
|
||||
false, /* isWrappedNative */
|
||||
nsOuterWindowProxy::ObjectMoved
|
||||
));
|
||||
|
||||
bool
|
||||
@ -1023,6 +1026,15 @@ nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
return js::UnwatchGuts(cx, proxy, id);
|
||||
}
|
||||
|
||||
void
|
||||
nsOuterWindowProxy::ObjectMoved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
nsGlobalWindow* global = GetWindow(obj);
|
||||
if (global) {
|
||||
global->UpdateWrapper(obj, old);
|
||||
}
|
||||
}
|
||||
|
||||
const nsOuterWindowProxy
|
||||
nsOuterWindowProxy::singleton;
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "js/Class.h"
|
||||
#include "js/Id.h" // must come before js/RootingAPI.h
|
||||
#include "js/Value.h" // must come before js/RootingAPI.h
|
||||
#include "js/RootingAPI.h"
|
||||
@ -44,6 +45,14 @@ class XPCWrappedNativeScope;
|
||||
*
|
||||
* The finalizer for the wrapper clears the cache.
|
||||
*
|
||||
* A compacting GC can move the wrapper object. Pointers to moved objects are
|
||||
* usually found and updated by tracing the heap, however non-preserved wrappers
|
||||
* are weak references and are not traced, so another approach is
|
||||
* necessary. Instead a class hook (objectMovedOp) is provided that is called
|
||||
* when an object is moved and is responsible for ensuring pointers are
|
||||
* updated. It does this by calling UpdateWrapper() on the wrapper
|
||||
* cache. SetWrapper() asserts that the hook is implemented for any wrapper set.
|
||||
*
|
||||
* A number of the methods are implemented in nsWrapperCacheInlines.h because we
|
||||
* have to include some JS headers that don't play nicely with the rest of the
|
||||
* codebase. Include nsWrapperCacheInlines.h if you need to call those methods.
|
||||
@ -89,6 +98,8 @@ public:
|
||||
{
|
||||
MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
|
||||
MOZ_ASSERT(aWrapper, "Use ClearWrapper!");
|
||||
MOZ_ASSERT(js::HasObjectMovedOp(aWrapper),
|
||||
"Object has not provided the hook to update the wrapper if it is moved");
|
||||
|
||||
SetWrapperJSObject(aWrapper);
|
||||
}
|
||||
@ -104,6 +115,18 @@ public:
|
||||
SetWrapperJSObject(nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the wrapper if the object it contains is moved.
|
||||
*
|
||||
* This method must be called from the objectMovedOp class extension hook for
|
||||
* any wrapper cached object.
|
||||
*/
|
||||
void UpdateWrapper(JSObject* aNewObject, const JSObject* aOldObject)
|
||||
{
|
||||
MOZ_ASSERT(mWrapper == aOldObject);
|
||||
mWrapper = aNewObject;
|
||||
}
|
||||
|
||||
bool PreservingWrapper()
|
||||
{
|
||||
return HasWrapperFlag(WRAPPER_BIT_PRESERVED);
|
||||
@ -162,7 +185,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* The following methods for getting and manipulating flags allow the unused
|
||||
* bits of mFlags to be used by derived classes.
|
||||
*/
|
||||
|
@ -1213,6 +1213,22 @@ ClearWrapper(T* p, void*)
|
||||
ClearWrapper(p, cache);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
UpdateWrapper(T* p, nsWrapperCache* cache, JSObject* obj, const JSObject* old)
|
||||
{
|
||||
cache->UpdateWrapper(obj, old);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void
|
||||
UpdateWrapper(T* p, void*, JSObject* obj, const JSObject* old)
|
||||
{
|
||||
nsWrapperCache* cache;
|
||||
CallQueryInterface(p, &cache);
|
||||
UpdateWrapper(p, cache, obj, old);
|
||||
}
|
||||
|
||||
// Attempt to preserve the wrapper, if any, for a Paris DOM bindings object.
|
||||
// Return true if we successfully preserved the wrapper, or there is no wrapper
|
||||
// to preserve. In the latter case we don't need to preserve the wrapper, because
|
||||
|
@ -17,6 +17,7 @@ AUTOGENERATED_WARNING_COMMENT = \
|
||||
"/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n"
|
||||
ADDPROPERTY_HOOK_NAME = '_addProperty'
|
||||
FINALIZE_HOOK_NAME = '_finalize'
|
||||
OBJECT_MOVED_HOOK_NAME = '_objectMoved'
|
||||
CONSTRUCT_HOOK_NAME = '_constructor'
|
||||
LEGACYCALLER_HOOK_NAME = '_legacycaller'
|
||||
HASINSTANCE_HOOK_NAME = '_hasInstance'
|
||||
@ -364,48 +365,61 @@ class CGDOMJSClass(CGThing):
|
||||
def define(self):
|
||||
traceHook = 'nullptr'
|
||||
callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
|
||||
objectMovedHook = OBJECT_MOVED_HOOK_NAME if self.descriptor.wrapperCache else 'nullptr'
|
||||
slotCount = INSTANCE_RESERVED_SLOTS + self.descriptor.interface.totalMembersInSlots
|
||||
classFlags = "JSCLASS_IS_DOMJSCLASS | "
|
||||
classExtensionAndObjectOps = """\
|
||||
JS_NULL_CLASS_EXT,
|
||||
JS_NULL_OBJECT_OPS
|
||||
"""
|
||||
classExtensionAndObjectOps = fill(
|
||||
"""
|
||||
{
|
||||
nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
${objectMoved} /* objectMovedOp */
|
||||
},
|
||||
JS_NULL_OBJECT_OPS
|
||||
""",
|
||||
objectMoved=objectMovedHook)
|
||||
if self.descriptor.isGlobal():
|
||||
classFlags += "JSCLASS_DOM_GLOBAL | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_IMPLEMENTS_BARRIERS"
|
||||
traceHook = "JS_GlobalObjectTraceHook"
|
||||
reservedSlots = "JSCLASS_GLOBAL_APPLICATION_SLOTS"
|
||||
if not self.descriptor.workers:
|
||||
classExtensionAndObjectOps = """\
|
||||
{
|
||||
nsGlobalWindow::OuterObject, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr /* weakmapKeyDelegateOp */
|
||||
},
|
||||
{
|
||||
nullptr, /* lookupGeneric */
|
||||
nullptr, /* lookupProperty */
|
||||
nullptr, /* lookupElement */
|
||||
nullptr, /* defineGeneric */
|
||||
nullptr, /* defineProperty */
|
||||
nullptr, /* defineElement */
|
||||
nullptr, /* getGeneric */
|
||||
nullptr, /* getProperty */
|
||||
nullptr, /* getElement */
|
||||
nullptr, /* setGeneric */
|
||||
nullptr, /* setProperty */
|
||||
nullptr, /* setElement */
|
||||
nullptr, /* getGenericAttributes */
|
||||
nullptr, /* setGenericAttributes */
|
||||
nullptr, /* deleteGeneric */
|
||||
nullptr, /* watch */
|
||||
nullptr, /* unwatch */
|
||||
nullptr, /* slice */
|
||||
nullptr, /* enumerate */
|
||||
JS_ObjectToOuterObject /* thisObject */
|
||||
}
|
||||
"""
|
||||
classExtensionAndObjectOps = fill(
|
||||
"""
|
||||
{
|
||||
nsGlobalWindow::OuterObject, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
${objectMoved} /* objectMovedOp */
|
||||
},
|
||||
{
|
||||
nullptr, /* lookupGeneric */
|
||||
nullptr, /* lookupProperty */
|
||||
nullptr, /* lookupElement */
|
||||
nullptr, /* defineGeneric */
|
||||
nullptr, /* defineProperty */
|
||||
nullptr, /* defineElement */
|
||||
nullptr, /* getGeneric */
|
||||
nullptr, /* getProperty */
|
||||
nullptr, /* getElement */
|
||||
nullptr, /* setGeneric */
|
||||
nullptr, /* setProperty */
|
||||
nullptr, /* setElement */
|
||||
nullptr, /* getGenericAttributes */
|
||||
nullptr, /* setGenericAttributes */
|
||||
nullptr, /* deleteGeneric */
|
||||
nullptr, /* watch */
|
||||
nullptr, /* unwatch */
|
||||
nullptr, /* slice */
|
||||
nullptr, /* enumerate */
|
||||
JS_ObjectToOuterObject /* thisObject */
|
||||
}
|
||||
""",
|
||||
objectMoved=objectMovedHook)
|
||||
else:
|
||||
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
|
||||
reservedSlots = slotCount
|
||||
@ -481,17 +495,24 @@ class CGDOMProxyJSClass(CGThing):
|
||||
# HTMLAllCollection. So just hardcode it here.
|
||||
if self.descriptor.interface.identifier.name == "HTMLAllCollection":
|
||||
flags.append("JSCLASS_EMULATES_UNDEFINED")
|
||||
objectMovedHook = OBJECT_MOVED_HOOK_NAME if self.descriptor.wrapperCache else 'nullptr'
|
||||
return fill(
|
||||
"""
|
||||
static const DOMJSClass Class = {
|
||||
PROXY_CLASS_DEF("${name}",
|
||||
0, /* extra slots */
|
||||
${flags}),
|
||||
PROXY_CLASS_WITH_EXT("${name}",
|
||||
0, /* extra slots */
|
||||
${flags},
|
||||
PROXY_MAKE_EXT(nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
${objectMoved})),
|
||||
$*{descriptor}
|
||||
};
|
||||
""",
|
||||
name=self.descriptor.interface.identifier.name,
|
||||
flags=" | ".join(flags),
|
||||
objectMoved=objectMovedHook,
|
||||
descriptor=DOMClass(self.descriptor))
|
||||
|
||||
|
||||
@ -1549,11 +1570,28 @@ class CGClassFinalizeHook(CGAbstractClassHook):
|
||||
return finalizeHook(self.descriptor, self.name, self.args[0].name).define()
|
||||
|
||||
|
||||
class CGClassObjectMovedHook(CGAbstractClassHook):
|
||||
"""
|
||||
A hook for objectMovedOp, used to update the wrapper cache when an object it
|
||||
is holding moves.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSObject*', 'obj'), Argument('const JSObject*', 'old')]
|
||||
CGAbstractClassHook.__init__(self, descriptor, OBJECT_MOVED_HOOK_NAME,
|
||||
'void', args)
|
||||
|
||||
def generate_code(self):
|
||||
assert self.descriptor.wrapperCache
|
||||
return CGIfWrapper(CGGeneric("UpdateWrapper(self, self, obj, old);\n"),
|
||||
"self").define()
|
||||
|
||||
|
||||
def JSNativeArguments():
|
||||
return [Argument('JSContext*', 'cx'),
|
||||
Argument('unsigned', 'argc'),
|
||||
Argument('JS::Value*', 'vp')]
|
||||
|
||||
|
||||
class CGClassConstructor(CGAbstractStaticMethod):
|
||||
"""
|
||||
JS-visible constructor for our objects
|
||||
@ -10919,6 +10957,9 @@ class CGDescriptor(CGThing):
|
||||
# wants a custom hook.
|
||||
cgThings.append(CGClassFinalizeHook(descriptor))
|
||||
|
||||
if descriptor.concrete and descriptor.wrapperCache:
|
||||
cgThings.append(CGClassObjectMovedHook(descriptor))
|
||||
|
||||
if len(descriptor.permissions):
|
||||
for (k, v) in sorted(descriptor.permissions.items()):
|
||||
perms = CGList((CGGeneric('"%s",' % p) for p in k), joiner="\n")
|
||||
|
@ -23,7 +23,8 @@ const js::Class OuterWrapperClass =
|
||||
nullptr, /* outerObject */
|
||||
js::proxy_innerObject,
|
||||
nullptr, /* iteratorObject */
|
||||
false /* isWrappedNative */
|
||||
false, /* isWrappedNative */
|
||||
nullptr /* objectMoved */
|
||||
));
|
||||
|
||||
static JSObject *
|
||||
|
@ -252,14 +252,14 @@ namespace js {
|
||||
* allow for potention JSClass extensions.
|
||||
*/
|
||||
#define PROXY_MAKE_EXT(outerObject, innerObject, iteratorObject, \
|
||||
isWrappedNative) \
|
||||
isWrappedNative, objectMoved) \
|
||||
{ \
|
||||
outerObject, \
|
||||
innerObject, \
|
||||
iteratorObject, \
|
||||
isWrappedNative, \
|
||||
js::proxy_WeakmapKeyDelegate, \
|
||||
js::proxy_ObjectMoved \
|
||||
objectMoved \
|
||||
}
|
||||
|
||||
#define PROXY_CLASS_WITH_EXT(name, extraSlots, flags, ext) \
|
||||
@ -313,7 +313,8 @@ namespace js {
|
||||
nullptr, /* outerObject */ \
|
||||
nullptr, /* innerObject */ \
|
||||
nullptr, /* iteratorObject */ \
|
||||
false /* isWrappedNative */ \
|
||||
false, /* isWrappedNative */ \
|
||||
js::proxy_ObjectMoved \
|
||||
))
|
||||
|
||||
/*
|
||||
|
@ -2374,7 +2374,6 @@ MovingTracer::Sweep(JSTracer *jstrc)
|
||||
// TODO: Should possibly just call PurgeRuntime() here.
|
||||
rt->newObjectCache.purge();
|
||||
rt->nativeIterCache.purge();
|
||||
rt->regExpTestCache.purge();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -49,6 +49,11 @@ public:
|
||||
ClearWrapper();
|
||||
}
|
||||
|
||||
void ObjectMoved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
UpdateWrapper(obj, old);
|
||||
}
|
||||
|
||||
private:
|
||||
virtual ~SandboxPrivate() { }
|
||||
|
||||
|
@ -310,7 +310,7 @@ sandbox_resolve(JSContext *cx, HandleObject obj, HandleId id)
|
||||
}
|
||||
|
||||
static void
|
||||
sandbox_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
sandbox_finalize(js::FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
nsIScriptObjectPrincipal *sop =
|
||||
static_cast<nsIScriptObjectPrincipal *>(xpc_GetJSPrivate(obj));
|
||||
@ -324,6 +324,15 @@ sandbox_finalize(JSFreeOp *fop, JSObject *obj)
|
||||
DestroyProtoAndIfaceCache(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
sandbox_moved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
nsIScriptObjectPrincipal *sop =
|
||||
static_cast<nsIScriptObjectPrincipal *>(xpc_GetJSPrivate(obj));
|
||||
MOZ_ASSERT(sop);
|
||||
static_cast<SandboxPrivate *>(sop)->ObjectMoved(obj, old);
|
||||
}
|
||||
|
||||
static bool
|
||||
sandbox_convert(JSContext *cx, HandleObject obj, JSType type, MutableHandleValue vp)
|
||||
{
|
||||
@ -443,22 +452,42 @@ sandbox_addProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleV
|
||||
|
||||
#define XPCONNECT_SANDBOX_CLASS_METADATA_SLOT (XPCONNECT_GLOBAL_EXTRA_SLOT_OFFSET)
|
||||
|
||||
static const JSClass SandboxClass = {
|
||||
static const js::Class SandboxClass = {
|
||||
"Sandbox",
|
||||
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
|
||||
JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize,
|
||||
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook
|
||||
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
{
|
||||
nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
sandbox_moved /* objectMovedOp */
|
||||
},
|
||||
JS_NULL_OBJECT_OPS
|
||||
};
|
||||
|
||||
// Note to whomever comes here to remove addProperty hooks: billm has promised
|
||||
// to do the work for this class.
|
||||
static const JSClass SandboxWriteToProtoClass = {
|
||||
static const js::Class SandboxWriteToProtoClass = {
|
||||
"Sandbox",
|
||||
XPCONNECT_GLOBAL_FLAGS_WITH_EXTRA_SLOTS(1),
|
||||
sandbox_addProperty, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize,
|
||||
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook
|
||||
nullptr, nullptr, nullptr, JS_GlobalObjectTraceHook,
|
||||
JS_NULL_CLASS_SPEC,
|
||||
{
|
||||
nullptr, /* outerObject */
|
||||
nullptr, /* innerObject */
|
||||
nullptr, /* iteratorObject */
|
||||
false, /* isWrappedNative */
|
||||
nullptr, /* weakmapKeyDelegateOp */
|
||||
sandbox_moved /* objectMovedOp */
|
||||
},
|
||||
JS_NULL_OBJECT_OPS
|
||||
};
|
||||
|
||||
static const JSFunctionSpec SandboxFunctions[] = {
|
||||
@ -471,7 +500,7 @@ static const JSFunctionSpec SandboxFunctions[] = {
|
||||
bool
|
||||
xpc::IsSandbox(JSObject *obj)
|
||||
{
|
||||
const JSClass *clasp = GetObjectJSClass(obj);
|
||||
const Class *clasp = GetObjectClass(obj);
|
||||
return clasp == &SandboxClass || clasp == &SandboxWriteToProtoClass;
|
||||
}
|
||||
|
||||
@ -861,11 +890,11 @@ xpc::CreateSandboxObject(JSContext *cx, MutableHandleValue vp, nsISupports *prin
|
||||
|
||||
compartmentOptions.setAddonId(addonId);
|
||||
|
||||
const JSClass *clasp = options.writeToGlobalPrototype
|
||||
? &SandboxWriteToProtoClass
|
||||
: &SandboxClass;
|
||||
const Class *clasp = options.writeToGlobalPrototype
|
||||
? &SandboxWriteToProtoClass
|
||||
: &SandboxClass;
|
||||
|
||||
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, clasp,
|
||||
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, js::Jsvalify(clasp),
|
||||
principal, compartmentOptions));
|
||||
if (!sandbox)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -991,6 +991,19 @@ XPCWrappedNative::FlatJSObjectFinalized()
|
||||
Release();
|
||||
}
|
||||
|
||||
void
|
||||
XPCWrappedNative::FlatJSObjectMoved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
MOZ_ASSERT(mFlatJSObject == old);
|
||||
|
||||
nsWrapperCache *cache = nullptr;
|
||||
CallQueryInterface(mIdentity, &cache);
|
||||
if (cache)
|
||||
cache->UpdateWrapper(obj, old);
|
||||
|
||||
mFlatJSObject = obj;
|
||||
}
|
||||
|
||||
void
|
||||
XPCWrappedNative::SystemIsBeingShutDown()
|
||||
{
|
||||
|
@ -572,6 +572,17 @@ WrappedNativeFinalize(js::FreeOp *fop, JSObject *obj, WNHelperType helperType)
|
||||
wrapper->FlatJSObjectFinalized();
|
||||
}
|
||||
|
||||
static void
|
||||
WrappedNativeObjectMoved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
|
||||
wrapper->FlatJSObjectMoved(obj, old);
|
||||
}
|
||||
|
||||
static void
|
||||
XPC_WN_NoHelper_Finalize(js::FreeOp *fop, JSObject *obj)
|
||||
{
|
||||
@ -658,7 +669,9 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
|
||||
nullptr, // outerObject
|
||||
nullptr, // innerObject
|
||||
nullptr, // iteratorObject
|
||||
true, // isWrappedNative
|
||||
true, // isWrappedNative
|
||||
nullptr, // weakmapKeyDelegateOp
|
||||
WrappedNativeObjectMoved
|
||||
},
|
||||
|
||||
// ObjectOps
|
||||
@ -1165,6 +1178,7 @@ XPCNativeScriptableShared::PopulateJSClass()
|
||||
mJSClass.base.trace = XPCWrappedNative::Trace;
|
||||
|
||||
mJSClass.base.ext.isWrappedNative = true;
|
||||
mJSClass.base.ext.objectMovedOp = WrappedNativeObjectMoved;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -2141,6 +2141,7 @@ public:
|
||||
nsresult RescueOrphans();
|
||||
|
||||
void FlatJSObjectFinalized();
|
||||
void FlatJSObjectMoved(JSObject *obj, const JSObject *old);
|
||||
|
||||
void SystemIsBeingShutDown();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user