Bug 650161 - Relocate global objects (browser changes) r=bholley

This commit is contained in:
Jon Coppeard 2014-10-20 09:07:43 +01:00
parent 7cc9536de3
commit 356b68ebfb
8 changed files with 79 additions and 25 deletions

View File

@ -106,7 +106,7 @@ public:
{
MOZ_ASSERT(!PreservingWrapper(), "Clearing a preserved wrapper!");
MOZ_ASSERT(aWrapper, "Use ClearWrapper!");
MOZ_ASSERT(js::HasObjectMovedOpIfRequired(aWrapper),
MOZ_ASSERT(js::HasObjectMovedOp(aWrapper),
"Object has not provided the hook to update the wrapper if it is moved");
SetWrapperJSObject(aWrapper);

View File

@ -580,10 +580,9 @@ IsObjectWithClass(const JS::Value &v, ESClassValue classValue, JSContext *cx);
inline bool
Unbox(JSContext *cx, JS::HandleObject obj, JS::MutableHandleValue vp);
/* Check whether the object's class supplies objectMovedOp for non-global objects. */
#ifdef DEBUG
JS_FRIEND_API(bool)
HasObjectMovedOpIfRequired(JSObject *obj);
HasObjectMovedOp(JSObject *obj);
#endif
} /* namespace js */

View File

@ -1440,7 +1440,7 @@ js::IsInRequest(JSContext *cx)
}
bool
js::HasObjectMovedOpIfRequired(JSObject *obj) {
js::HasObjectMovedOp(JSObject *obj) {
return !!GetObjectClass(obj)->ext.objectMovedOp;
}
#endif

View File

@ -55,6 +55,11 @@ public:
MOZ_CRASH("SandboxPrivate doesn't use DOM bindings!");
}
void ObjectMoved(JSObject *obj, const JSObject *old)
{
UpdateWrapper(obj, old);
}
private:
virtual ~SandboxPrivate() { }

View File

@ -15,6 +15,8 @@
#include "js/HeapAPI.h"
class XPCWrappedNative;
class BackstagePass : public nsIGlobalObject,
public nsIScriptObjectPrincipal,
public nsIXPCScriptable,
@ -30,17 +32,13 @@ public:
return mPrincipal;
}
virtual JSObject* GetGlobalJSObject() {
return mGlobal;
}
virtual JSObject* GetGlobalJSObject();
virtual void ForgetGlobalObject() {
mGlobal = nullptr;
mWrapper = nullptr;
}
virtual void SetGlobalObject(JSObject* global) {
mGlobal = global;
}
virtual void SetGlobalObject(JSObject* global);
explicit BackstagePass(nsIPrincipal *prin) :
mPrincipal(prin)
@ -51,7 +49,7 @@ private:
virtual ~BackstagePass() { }
nsCOMPtr<nsIPrincipal> mPrincipal;
JS::TenuredHeap<JSObject*> mGlobal;
XPCWrappedNative *mWrapper;
};
nsresult

View File

@ -311,7 +311,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));
@ -325,6 +325,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)
{
@ -444,22 +453,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[] = {
@ -472,7 +501,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;
}
@ -875,11 +904,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;

View File

@ -4,6 +4,8 @@
* 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/. */
#include "xpcprivate.h"
#include "nsContentUtils.h"
#include "BackstagePass.h"
#include "nsIProgrammingLanguage.h"
@ -43,6 +45,23 @@ NS_IMPL_RELEASE(BackstagePass)
nsIXPCScriptable::DONT_REFLECT_INTERFACE_NAMES
#include "xpc_map_end.h" /* This will #undef the above */
JSObject *
BackstagePass::GetGlobalJSObject()
{
if (mWrapper)
return mWrapper->GetFlatJSObject();
return nullptr;
}
void
BackstagePass::SetGlobalObject(JSObject* global)
{
nsISupports* p = XPCWrappedNative::Get(global);
MOZ_ASSERT(p);
mWrapper = static_cast<XPCWrappedNative*>(p);
}
/* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, out JSObjectPtr objp); */
NS_IMETHODIMP
BackstagePass::NewResolve(nsIXPConnectWrappedNative *wrapper,

View File

@ -511,9 +511,13 @@ XPCWrappedNativeScope::UpdateWeakPointersAfterGC(XPCJSRuntime* rt)
XPCWrappedNativeScope* next = cur->mNext;
// Check for finalization of the global object. Note that global
// objects are never moved, so we don't need to handle updating the
// object pointer here.
if (cur->mContentXBLScope)
cur->mContentXBLScope.updateWeakPointerAfterGC();
for (size_t i = 0; i < cur->mAddonScopes.Length(); i++)
cur->mAddonScopes[i].updateWeakPointerAfterGC();
// Check for finalization of the global object or update our pointer if
// it was moved.
if (cur->mGlobalJSObject) {
cur->mGlobalJSObject.updateWeakPointerAfterGC();
if (!cur->mGlobalJSObject) {