Bug 633879 - Stop wrappers from holding old scopes alive. r=mrbkap@gmail.com,jst@mozilla.com, a=blocker

This commit is contained in:
Andreas Gal 2011-02-14 14:19:36 -08:00
Родитель 8f23700918
Коммит 31e333792b
4 изменённых файлов: 21 добавлений и 12 удалений

Просмотреть файл

@ -45,6 +45,7 @@
#include "jsproxy.h"
#include "jsscope.h"
#include "jstracer.h"
#include "jswrapper.h"
#include "assembler/wtf/Platform.h"
#include "methodjit/MethodJIT.h"
#include "methodjit/PolyIC.h"
@ -176,6 +177,12 @@ JSCompartment::arenaListsAreEmpty()
return true;
}
static bool
IsCrossCompartmentWrapper(JSObject *wrapper)
{
return !!(JSWrapper::wrapperHandler(wrapper)->flags() & JSWrapper::CROSS_COMPARTMENT);
}
bool
JSCompartment::wrap(JSContext *cx, Value *vp)
{
@ -276,8 +283,16 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
/* If we already have a wrapper for this value, use it. */
if (WrapperMap::Ptr p = crossCompartmentWrappers.lookup(*vp)) {
*vp = p->value;
if (vp->isObject())
vp->toObject().setParent(global);
if (vp->isObject()) {
JSObject *obj = &vp->toObject();
JS_ASSERT(IsCrossCompartmentWrapper(obj));
if (obj->getParent() != global) {
do {
obj->setParent(global);
obj = obj->getProto();
} while (obj && IsCrossCompartmentWrapper(obj));
}
}
return true;
}

Просмотреть файл

@ -417,12 +417,6 @@ JSCrossCompartmentWrapper::~JSCrossCompartmentWrapper()
{
}
bool
JSCrossCompartmentWrapper::isCrossCompartmentWrapper(JSObject *obj)
{
return obj->isProxy() && obj->getProxyHandler() == &JSCrossCompartmentWrapper::singleton;
}
#define PIERCE(cx, wrapper, mode, pre, op, post) \
JS_BEGIN_MACRO \
AutoCompartment call(cx, wrappedObject(wrapper)); \

Просмотреть файл

@ -151,8 +151,6 @@ class JS_FRIEND_API(JSCrossCompartmentWrapper) : public JSWrapper {
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
static bool isCrossCompartmentWrapper(JSObject *obj);
static JSCrossCompartmentWrapper singleton;
};

Просмотреть файл

@ -3459,8 +3459,10 @@ EvalInContext(JSContext *cx, uintN argc, jsval *vp)
JSStackFrame *fp = JS_GetScriptedCaller(cx, NULL);
{
JSAutoEnterCompartment ac;
if (JSCrossCompartmentWrapper::isCrossCompartmentWrapper(sobj)) {
sobj = sobj->unwrap();
uintN flags;
JSObject *unwrapped = sobj->unwrap(&flags);
if (flags & JSWrapper::CROSS_COMPARTMENT) {
sobj = unwrapped;
if (!ac.enter(cx, sobj))
return false;
}